Skip to content

Commit

Permalink
[#30] Add more test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
manh-t committed Sep 7, 2023
1 parent 5810dc1 commit 1e925a5
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 23 deletions.
50 changes: 41 additions & 9 deletions src/components/Answer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,63 @@ const Answer = ({ question, ...rest }: AnswerProps): JSX.Element => {
case DisplayType.Star:
return (
<Rating
questionId={question.id}
items={question.answers}
displayType={displayTypeEnum}
data-test-id={rest['data-test-id']}
onValueChanged={() => {
// TODO
}}
/>
);
case DisplayType.Choice:
return (
<MultiChoice
questionId={question.id}
items={question.answers}
isPickOne={question?.pick === 'one'}
data-test-id={rest['data-test-id']}
onValuesChanged={() => {
// TODO
}}
/>
);
case DisplayType.Nps:
return <Nps questionId={question.id} items={question.answers} data-test-id={rest['data-test-id']} />;
return (
<Nps
items={question.answers}
onValuesChanged={() => {
// TODO
}}
/>
);
case DisplayType.Textarea:
return <TextArea questionId={question.id} items={question.answers} data-test-id={rest['data-test-id']} />;
return (
<TextArea
items={question.answers}
onValueChange={() => {
// TODO
}}
/>
);
case DisplayType.Textfield:
return <MultiInputs questionId={question.id} items={question.answers} data-test-id={rest['data-test-id']} />;
return <MultiInputs questionId={question.id} items={question.answers} />;
case DisplayType.Dropdown:
return <Dropdown questionId={question.id} items={question.answers} data-test-id={rest['data-test-id']} />;
return (
<Dropdown
questionId={question.id}
items={question.answers}
onValueChanged={() => {
// TODO
}}
/>
);
case DisplayType.Slider:
return <AppSlider questionId={question.id} items={question.answers} data-test-id={rest['data-test-id']} />;
return (
<AppSlider
min={0}
max={question.answers.length}
onValueChanged={() => {
// TODO
}}
/>
);
case DisplayType.Unknown:
case DisplayType.Intro:
case DisplayType.Outro:
Expand Down
107 changes: 106 additions & 1 deletion src/screens/Question/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
import React from 'react';

import { render, screen } from '@testing-library/react';
import { act, render, screen } from '@testing-library/react';

import { useAppDispatch, useAppSelector } from 'hooks';
import { SurveyState } from 'store/reducers/Survey';
import TestWrapper from 'tests/TestWrapper';

import QuestionScreen, { questionScreenTestIds } from '.';

const mockDispatch = jest.fn();
const mockUseNavigate = jest.fn();

jest.mock('hooks');
jest.mock('react-router-dom', () => ({
...(jest.requireActual('react-router-dom') as jest.Mock),
useNavigate: () => mockUseNavigate,
}));

describe('QuestionScreen', () => {
const TestComponent = (): JSX.Element => {
return (
Expand All @@ -15,17 +26,111 @@ describe('QuestionScreen', () => {
);
};

const mockState: { survey: SurveyState } = {
survey: {
survey: {
id: 'd5de6a8f8f5f1cfe51bc',
resourceType: 'survey',
title: 'Scarlett Bangkok',
description: "We'd love ot hear from you!",
coverImageUrl: 'https://dhdbhh0jsld0o.cloudfront.net/m/1ea51560991bcb7d00d0_',
questions: [
{
id: 'question 1',
resourceType: 'question',
text: 'Question 1',
displayType: 'intro',
answers: [],
},
{
id: 'question 2',
resourceType: 'question',
text: 'Question 2',
displayType: 'slider',
answers: [
{
id: 'answer 1',
resourceType: 'answer',
text: 'Answer 1',
},
{
id: 'answer 2',
resourceType: 'answer',
text: 'Answer 2',
},
],
},
{
id: 'question 3',
resourceType: 'question',
text: 'Question 3',
displayType: 'outro',
answers: [],
},
],
},
isLoading: true,
isError: false,
},
};

beforeEach(() => {
(useAppSelector as jest.Mock).mockImplementation((callback) => callback(mockState));
(useAppDispatch as jest.Mock).mockImplementation(() => mockDispatch);
});

afterEach(() => {
jest.clearAllMocks();
});

it('renders Question screen and its components', () => {
render(<TestComponent />);

const currentIndex = screen.getByTestId(questionScreenTestIds.index);
const questionTitle = screen.getByTestId(questionScreenTestIds.title);
const answerComponent = screen.getByTestId(questionScreenTestIds.answer);
const closeButton = screen.getByTestId(questionScreenTestIds.closeButton);
const nextButton = screen.getByTestId(questionScreenTestIds.nextButton);

expect(currentIndex).toBeVisible();
expect(currentIndex).toHaveTextContent('1/3');
expect(questionTitle).toBeVisible();
expect(questionTitle).toHaveTextContent('Question 1');
expect(answerComponent).toBeVisible();
expect(closeButton).toBeVisible();
expect(nextButton).toBeVisible();
});

describe('given the next button is clicked', () => {
it('renders the next question', () => {
render(<TestComponent />);

const currentIndex = screen.getByTestId(questionScreenTestIds.index);
const questionTitle = screen.getByTestId(questionScreenTestIds.title);
const nextButton = screen.getByTestId(questionScreenTestIds.nextButton);

act(() => {
nextButton.click();
});

expect(currentIndex).toBeVisible();
expect(currentIndex).toHaveTextContent('2/3');
expect(questionTitle).toBeVisible();
expect(questionTitle).toHaveTextContent('Question 2');
});
});

describe('given the close button is clicked', () => {
it('navigates back to the previous screen', () => {
render(<TestComponent />);

const closeButton = screen.getByTestId(questionScreenTestIds.closeButton);

act(() => {
closeButton.click();
});

expect(mockUseNavigate).toHaveBeenCalledWith(-1);
});
});
});
4 changes: 3 additions & 1 deletion src/screens/Question/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { useAppSelector } from 'hooks';
export const questionScreenTestIds = {
index: 'question__index',
title: 'question__title',
answer: 'question__answer',
closeButton: 'question__close-button',
nextButton: 'question__next-button',
};
Expand Down Expand Up @@ -60,7 +61,8 @@ const QuestionScreen = (): JSX.Element => {
</p>
{currentQuestion && (
<div className="mt-16">
<Answer question={currentQuestion} />
<p>{currentQuestion.displayType}</p>
<Answer question={currentQuestion} data-test-id={questionScreenTestIds.answer} />
</div>
)}
</div>
Expand Down
9 changes: 1 addition & 8 deletions src/store/reducers/Survey/action.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
import { AsyncThunkPayloadCreator } from '@reduxjs/toolkit';

import { getSurvey, submitSurvey } from 'adapters/Survey';
import { getSurvey } from 'adapters/Survey';
import { DeserializableResponse, deserialize } from 'helpers/deserializer';
import { JSONObject } from 'helpers/json';
import { SurveySubmitRequest } from 'types/request/surveySubmitRequest';
import { Survey } from 'types/survey';

export const getSurveyThunkCreator: AsyncThunkPayloadCreator<Survey, string, JSONObject> = async (surveyId: string) => {
return getSurvey(surveyId).then((response: DeserializableResponse) => deserialize<Survey>(response.data, response.included));
};

export const submitSurveyThunkCreator: AsyncThunkPayloadCreator<void, SurveySubmitRequest, JSONObject> = (
surveySubmitRequest
) => {
return submitSurvey(surveySubmitRequest).then();
};
4 changes: 1 addition & 3 deletions src/store/reducers/Survey/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import { SurveySubmitRequest } from 'types/request/surveySubmitRequest';
import { Survey } from 'types/survey';

import { getSurveyThunkCreator, submitSurveyThunkCreator } from './action';
import { getSurveyThunkCreator } from './action';

export interface SurveyState {
survey?: Survey;
Expand All @@ -19,8 +19,6 @@ export const initialState: SurveyState = {

export const getSurveyAsyncThunk = createAsyncThunk('survey/getSurvey', getSurveyThunkCreator);

export const submitSurveyAsyncThunk = createAsyncThunk('survey/submitSurvey', submitSurveyThunkCreator);

export const surveySlice = createSlice({
name: 'survey',
initialState,
Expand Down
4 changes: 3 additions & 1 deletion src/types/question.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import capitalize from 'lodash/capitalize';

import { Resource } from 'types/resource';

import { Answer } from './answer';
Expand Down Expand Up @@ -34,5 +36,5 @@ export enum DisplayType {
}

export const getDisplayTypeEnum = (question: Question): DisplayType => {
return question.displayType ? (<never>DisplayType)[question.displayType] : DisplayType.Unknown;
return DisplayType[capitalize(question.displayType) as keyof typeof DisplayType] ?? DisplayType.Unknown;
};

0 comments on commit 1e925a5

Please sign in to comment.