Skip to content
Snippets Groups Projects
Commit 8eea9f3d authored by Adrian Orłów's avatar Adrian Orłów
Browse files

test: add tests for backgrounds, overlays, project

parent ec99154f
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...,!43feat: add map full data mgmt
Pipeline #80302 passed
Showing
with 303 additions and 15 deletions
import { bioEntitiesContentFixture } from '@/models/fixtures/bioEntityContentsFixture';
import { MODELS_MOCK } from '@/models/mocks/modelsMock';
import { StoreType } from '@/redux/store';
import { Accordion } from '@/shared/Accordion';
import {
InitialStoreState,
getReduxWrapperWithStore,
} from '@/utils/testing/getReduxWrapperWithStore';
import { render, screen } from '@testing-library/react';
import { bioEntitiesContentFixture } from '@/models/fixtures/bioEntityContentsFixture';
import { Accordion } from '@/shared/Accordion';
import { MODELS_MOCK } from '@/models/mocks/modelsMock';
import { BioEntitiesAccordion } from './BioEntitiesAccordion.component';
const renderComponent = (initialStoreState: InitialStoreState = {}): { store: StoreType } => {
......@@ -35,7 +35,7 @@ describe('BioEntitiesAccordion - component', () => {
error: { name: '', message: '' },
},
models: {
data: undefined,
data: [],
loading: 'pending',
error: { name: '', message: '' },
},
......
import { ZOD_SEED } from '@/constants';
import { z } from 'zod';
// eslint-disable-next-line import/no-extraneous-dependencies
import { createFixture } from 'zod-fixture';
import { mapBackground } from '../mapBackground';
export const backgroundsFixture = createFixture(z.array(mapBackground), {
seed: ZOD_SEED,
array: { min: 2, max: 2 },
});
import { ZOD_SEED } from '@/constants';
import { z } from 'zod';
// eslint-disable-next-line import/no-extraneous-dependencies
import { createFixture } from 'zod-fixture';
import { mapOverlay } from '../mapOverlay';
export const overlaysFixture = createFixture(z.array(mapOverlay), {
seed: ZOD_SEED,
array: { min: 2, max: 2 },
});
import { ZOD_SEED } from '@/constants';
// eslint-disable-next-line import/no-extraneous-dependencies
import { createFixture } from 'zod-fixture';
import { projectSchema } from '../project';
export const projectFixture = createFixture(projectSchema, {
seed: ZOD_SEED,
array: { min: 1, max: 1 },
});
......@@ -16,4 +16,5 @@ export const apiPath = {
): string => `projects/${projectId}/overlays/?publicOverlay=${String(publicOverlay)}`,
getAllBackgroundsByProjectIdQuery: (projectId: string): string =>
`projects/${projectId}/backgrounds/`,
getProjectById: (projectId: string): string => `projects/${projectId}`,
};
import { PROJECT_ID } from '@/constants';
import { backgroundsFixture } from '@/models/fixtures/backgroundsFixture';
import {
ToolkitStoreWithSingleSlice,
createStoreInstanceUsingSliceReducer,
} from '@/utils/createStoreInstanceUsingSliceReducer';
import { mockNetworkResponse } from '@/utils/mockNetworkResponse';
import { HttpStatusCode } from 'axios';
import { apiPath } from '../apiPath';
import backgroundsReducer from './backgrounds.slice';
import { getAllBackgroundsByProjectId } from './backgrounds.thunks';
import { BackgroundsState } from './backgrounds.types';
const mockedAxiosClient = mockNetworkResponse();
const INITIAL_STATE: BackgroundsState = {
data: [],
loading: 'idle',
error: { name: '', message: '' },
};
describe('backgrounds reducer', () => {
let store = {} as ToolkitStoreWithSingleSlice<BackgroundsState>;
beforeEach(() => {
store = createStoreInstanceUsingSliceReducer('backgrounds', backgroundsReducer);
});
it('should match initial state', () => {
const action = { type: 'unknown' };
expect(backgroundsReducer(undefined, action)).toEqual(INITIAL_STATE);
});
it('should update store after succesfull getAllBackgroundsByProjectId query', async () => {
mockedAxiosClient
.onGet(apiPath.getAllBackgroundsByProjectIdQuery(PROJECT_ID))
.reply(HttpStatusCode.Ok, backgroundsFixture);
const { type } = await store.dispatch(getAllBackgroundsByProjectId(PROJECT_ID));
const { data, loading, error } = store.getState().backgrounds;
expect(type).toBe('backgrounds/getAllBackgroundsByProjectId/fulfilled');
expect(loading).toEqual('succeeded');
expect(error).toEqual({ message: '', name: '' });
expect(data).toEqual(backgroundsFixture);
});
it('should update store after failed getAllBackgroundsByProjectId query', async () => {
mockedAxiosClient
.onGet(apiPath.getAllBackgroundsByProjectIdQuery(PROJECT_ID))
.reply(HttpStatusCode.NotFound, []);
const { type } = await store.dispatch(getAllBackgroundsByProjectId(PROJECT_ID));
const { data, loading, error } = store.getState().backgrounds;
expect(type).toBe('backgrounds/getAllBackgroundsByProjectId/rejected');
expect(loading).toEqual('failed');
expect(error).toEqual({ message: '', name: '' });
expect(data).toEqual([]);
});
it('should update store on loading getAllBackgroundsByProjectId query', async () => {
mockedAxiosClient
.onGet(apiPath.getAllBackgroundsByProjectIdQuery(PROJECT_ID))
.reply(HttpStatusCode.Ok, backgroundsFixture);
const actionPromise = store.dispatch(getAllBackgroundsByProjectId(PROJECT_ID));
const { data, loading } = store.getState().backgrounds;
expect(data).toEqual([]);
expect(loading).toEqual('pending');
actionPromise.then(() => {
const { data: dataPromiseFulfilled, loading: promiseFulfilled } =
store.getState().backgrounds;
expect(dataPromiseFulfilled).toEqual(backgroundsFixture);
expect(promiseFulfilled).toEqual('succeeded');
});
});
});
......@@ -5,8 +5,15 @@ import { BackgroundsState } from './backgrounds.types';
export const getAllBackgroundsByProjectIdReducer = (
builder: ActionReducerMapBuilder<BackgroundsState>,
): void => {
builder.addCase(getAllBackgroundsByProjectId.pending, state => {
state.loading = 'pending';
});
builder.addCase(getAllBackgroundsByProjectId.fulfilled, (state, action) => {
state.data = action.payload || [];
state.loading = 'succeeded';
});
builder.addCase(getAllBackgroundsByProjectId.rejected, state => {
state.loading = 'failed';
// TODO to discuss manage state of failure
});
};
......@@ -7,7 +7,7 @@ import { z } from 'zod';
import { apiPath } from '../apiPath';
export const getAllBackgroundsByProjectId = createAsyncThunk(
'models/getAllBackgroundsByProjectId',
'backgrounds/getAllBackgroundsByProjectId',
async (projectId: string): Promise<MapBackground[]> => {
const response = await axiosInstance.get<MapBackground[]>(
apiPath.getAllBackgroundsByProjectIdQuery(projectId),
......
import { HttpStatusCode } from 'axios';
import { modelsFixture } from '@/models/fixtures/modelsFixture';
import { mockNetworkResponse } from '@/utils/mockNetworkResponse';
import { apiPath } from '@/redux/apiPath';
import {
ToolkitStoreWithSingleSlice,
createStoreInstanceUsingSliceReducer,
} from '@/utils/createStoreInstanceUsingSliceReducer';
import { apiPath } from '@/redux/apiPath';
import { getModels } from './models.thunks';
import { mockNetworkResponse } from '@/utils/mockNetworkResponse';
import { HttpStatusCode } from 'axios';
import modelsReducer from './models.slice';
import { getModels } from './models.thunks';
import { ModelsState } from './models.types';
const mockedAxiosClient = mockNetworkResponse();
......
import { FetchDataState } from '@/types/fetchDataState';
import { MapModel } from '@/types/models';
export type ModelsState = FetchDataState<MapModel[] | []>;
export type ModelsState = FetchDataState<MapModel[], []>;
import { PROJECT_ID } from '@/constants';
import { overlaysFixture } from '@/models/fixtures/overlaysFixture';
import {
ToolkitStoreWithSingleSlice,
createStoreInstanceUsingSliceReducer,
} from '@/utils/createStoreInstanceUsingSliceReducer';
import { mockNetworkResponse } from '@/utils/mockNetworkResponse';
import { HttpStatusCode } from 'axios';
import { apiPath } from '../apiPath';
import overlaysReducer from './overlays.slice';
import { getAllPublicOverlaysByProjectId } from './overlays.thunks';
import { OverlaysState } from './overlays.types';
const mockedAxiosClient = mockNetworkResponse();
const INITIAL_STATE: OverlaysState = {
data: [],
loading: 'idle',
error: { name: '', message: '' },
};
describe('overlays reducer', () => {
let store = {} as ToolkitStoreWithSingleSlice<OverlaysState>;
beforeEach(() => {
store = createStoreInstanceUsingSliceReducer('overlays', overlaysReducer);
});
it('should match initial state', () => {
const action = { type: 'unknown' };
expect(overlaysReducer(undefined, action)).toEqual(INITIAL_STATE);
});
it('should update store after succesfull getAllPublicOverlaysByProjectId query', async () => {
mockedAxiosClient
.onGet(apiPath.getAllOverlaysByProjectIdQuery(PROJECT_ID, { publicOverlay: true }))
.reply(HttpStatusCode.Ok, overlaysFixture);
const { type } = await store.dispatch(getAllPublicOverlaysByProjectId(PROJECT_ID));
const { data, loading, error } = store.getState().overlays;
expect(type).toBe('overlays/getAllPublicOverlaysByProjectId/fulfilled');
expect(loading).toEqual('succeeded');
expect(error).toEqual({ message: '', name: '' });
expect(data).toEqual(overlaysFixture);
});
it('should update store after failed getAllPublicOverlaysByProjectId query', async () => {
mockedAxiosClient
.onGet(apiPath.getAllOverlaysByProjectIdQuery(PROJECT_ID, { publicOverlay: true }))
.reply(HttpStatusCode.NotFound, []);
const { type } = await store.dispatch(getAllPublicOverlaysByProjectId(PROJECT_ID));
const { data, loading, error } = store.getState().overlays;
expect(type).toBe('overlays/getAllPublicOverlaysByProjectId/rejected');
expect(loading).toEqual('failed');
expect(error).toEqual({ message: '', name: '' });
expect(data).toEqual([]);
});
it('should update store on loading getAllPublicOverlaysByProjectId query', async () => {
mockedAxiosClient
.onGet(apiPath.getAllOverlaysByProjectIdQuery(PROJECT_ID, { publicOverlay: true }))
.reply(HttpStatusCode.Ok, overlaysFixture);
const actionPromise = store.dispatch(getAllPublicOverlaysByProjectId(PROJECT_ID));
const { data, loading } = store.getState().overlays;
expect(data).toEqual([]);
expect(loading).toEqual('pending');
actionPromise.then(() => {
const { data: dataPromiseFulfilled, loading: promiseFulfilled } = store.getState().overlays;
expect(dataPromiseFulfilled).toEqual(overlaysFixture);
expect(promiseFulfilled).toEqual('succeeded');
});
});
});
......@@ -5,8 +5,15 @@ import { OverlaysState } from './overlays.types';
export const getAllPublicOverlaysByProjectIdReducer = (
builder: ActionReducerMapBuilder<OverlaysState>,
): void => {
builder.addCase(getAllPublicOverlaysByProjectId.pending, state => {
state.loading = 'pending';
});
builder.addCase(getAllPublicOverlaysByProjectId.fulfilled, (state, action) => {
state.data = action.payload || [];
state.loading = 'succeeded';
});
builder.addCase(getAllPublicOverlaysByProjectId.rejected, state => {
state.loading = 'failed';
// TODO to discuss manage state of failure
});
};
......@@ -7,7 +7,7 @@ import { z } from 'zod';
import { apiPath } from '../apiPath';
export const getAllPublicOverlaysByProjectId = createAsyncThunk(
'models/getAllPublicOverlaysByProjectId',
'overlays/getAllPublicOverlaysByProjectId',
async (projectId: string): Promise<MapOverlay[]> => {
const response = await axiosInstance.get<MapOverlay[]>(
apiPath.getAllOverlaysByProjectIdQuery(projectId, { publicOverlay: true }),
......
import { PROJECT_ID } from '@/constants';
import { projectFixture } from '@/models/fixtures/projectFixture';
import {
ToolkitStoreWithSingleSlice,
createStoreInstanceUsingSliceReducer,
} from '@/utils/createStoreInstanceUsingSliceReducer';
import { mockNetworkResponse } from '@/utils/mockNetworkResponse';
import { HttpStatusCode } from 'axios';
import { apiPath } from '../apiPath';
import projectReducer from './project.slice';
import { getProjectById } from './project.thunks';
import { ProjectState } from './project.types';
const mockedAxiosClient = mockNetworkResponse();
const INITIAL_STATE: ProjectState = {
data: undefined,
loading: 'idle',
error: { name: '', message: '' },
};
describe('project reducer', () => {
let store = {} as ToolkitStoreWithSingleSlice<ProjectState>;
beforeEach(() => {
store = createStoreInstanceUsingSliceReducer('project', projectReducer);
});
it('should match initial state', () => {
const action = { type: 'unknown' };
expect(projectReducer(undefined, action)).toEqual(INITIAL_STATE);
});
it('should update store after succesfull getProjectById query', async () => {
mockedAxiosClient
.onGet(apiPath.getProjectById(PROJECT_ID))
.reply(HttpStatusCode.Ok, projectFixture);
const { type } = await store.dispatch(getProjectById(PROJECT_ID));
const { data, loading, error } = store.getState().project;
expect(type).toBe('project/getProjectById/fulfilled');
expect(loading).toEqual('succeeded');
expect(error).toEqual({ message: '', name: '' });
expect(data).toEqual(projectFixture);
});
it('should update store after failed getProjectById query', async () => {
mockedAxiosClient.onGet(apiPath.getProjectById(PROJECT_ID)).reply(HttpStatusCode.NotFound, []);
const { type } = await store.dispatch(getProjectById(PROJECT_ID));
const { data, loading, error } = store.getState().project;
expect(type).toBe('project/getProjectById/rejected');
expect(loading).toEqual('failed');
expect(error).toEqual({ message: '', name: '' });
expect(data).toEqual(undefined);
});
it('should update store on loading getProjectById query', async () => {
mockedAxiosClient
.onGet(apiPath.getProjectById(PROJECT_ID))
.reply(HttpStatusCode.Ok, projectFixture);
const actionPromise = store.dispatch(getProjectById(PROJECT_ID));
const { data, loading } = store.getState().project;
expect(data).toEqual(undefined);
expect(loading).toEqual('pending');
actionPromise.then(() => {
const { data: dataPromiseFulfilled, loading: promiseFulfilled } = store.getState().project;
expect(dataPromiseFulfilled).toEqual(projectFixture);
expect(promiseFulfilled).toEqual('succeeded');
});
});
});
import { ActionReducerMapBuilder } from '@reduxjs/toolkit';
import { ProjectState } from '@/redux/project/project.types';
import { getProjectById } from '@/redux/project/project.thunks';
import { ProjectState } from '@/redux/project/project.types';
import { ActionReducerMapBuilder } from '@reduxjs/toolkit';
export const getProjectByIdReducer = (builder: ActionReducerMapBuilder<ProjectState>): void => {
builder.addCase(getProjectById.pending, state => {
state.loading = 'pending';
});
builder.addCase(getProjectById.fulfilled, (state, action) => {
state.data = action.payload;
state.data = action.payload || undefined;
state.loading = 'succeeded';
});
builder.addCase(getProjectById.rejected, state => {
state.loading = 'failed';
// TODO to discuss manage state of failure
});
};
......@@ -3,11 +3,12 @@ import { axiosInstance } from '@/services/api/utils/axiosInstance';
import { Project } from '@/types/models';
import { validateDataUsingZodSchema } from '@/utils/validateDataUsingZodSchema';
import { createAsyncThunk } from '@reduxjs/toolkit';
import { apiPath } from '../apiPath';
export const getProjectById = createAsyncThunk(
'project/getProjectById',
async (id: string): Promise<Project | undefined> => {
const response = await axiosInstance.get<Project>(`projects/${id}`);
const response = await axiosInstance.get<Project>(apiPath.getProjectById(id));
const isDataValid = validateDataUsingZodSchema(response.data, projectSchema);
......
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