Fakultas Ilmu Komputer UI

Commit 094388fd authored by Wulan Mantiri's avatar Wulan Mantiri
Browse files

Merge branch 'PBI-13-improve_test_weekly_report' into 'staging'

Improve tests for client weekly report

See merge request !73
parents 59d47491 0e3b5036
Pipeline #81655 passed with stages
in 48 minutes and 58 seconds
......@@ -46,7 +46,6 @@ const LikertScale: FC<Props> = ({
style={{ flex: 1 / choices.length }}
key={`button${choice.value}`}>
<RadioButton
testID={`${label}-${value}`}
key={choice.value}
checked={value === choice.value}
onPress={() => onChange(choice.value)}
......
......@@ -17,10 +17,10 @@ import {
Questionnaire4,
Questionnaire5,
} from 'scenes/questionnaire/ExtendedQuestionnaire/components';
import ReadOnlyWeeklyReport from 'scenes/report/ReadOnlyWeeklyReport';
import { screenOptions } from 'app/styles';
import { styles } from './styles';
import { ReadOnlyWeeklyReport } from 'scenes';
interface NavRoute<T = any> {
name: string;
......
......@@ -9,7 +9,7 @@ import { generateValidationSchema } from 'utils/form';
import { DietReportPage } from './components';
import { useRoute, useNavigation } from '@react-navigation/native';
import {
retrieveUserReportById,
retrieveUserReportByIdApi,
createNutritionistCommentApi,
} from 'services/progress';
import { NutritionistCommentRequest } from 'services/progress/models';
......@@ -28,7 +28,7 @@ const DietReportForNutritionist: FC = () => {
const route = useRoute();
const { id } = route.params as ParamsDietReport;
const { isLoading, data: userReports = [] } = useApi(() =>
retrieveUserReportById(id),
retrieveUserReportByIdApi(id),
);
const [activeSlide, setActiveSlide] = useState(1);
......
......@@ -14,7 +14,10 @@ const Report2: FC<ReportProps> = ({ getTextInputProps, getFormFieldProps }) => (
{dietReportSelectFields.dietReportPage2.map((props, i) => {
const FormField = props.scaleDescription ? LikertScale : RadioButtonGroup;
return (
<View key={`report2-select${i}`} style={styles.spacing}>
<View
key={`report2-select${i}`}
style={styles.spacing}
testID={props.name}>
<FormField
{...props}
choices={props.choiceList.map((label: string, id: number) => ({
......
......@@ -14,7 +14,10 @@ const Report3: FC<ReportProps> = ({ getFormFieldProps }) => (
atau minuman dibawah ini selama seharian:
</Text>
{dietReportSelectFields.dietReportPage3.map((props, i) => (
<View key={`report3-scale${i}`} style={styles.spacing}>
<View
key={`report3-scale${i}`}
style={styles.spacing}
testID={props.name}>
<LikertScale
{...props}
{...getFormFieldProps(props.name)}
......
import React from 'react';
import { render, fireEvent, waitFor } from '@testing-library/react-native';
import axios from 'axios';
import WeeklyReport from '.';
import {
dietReportTextFields,
dietReportSelectFields,
} from 'constants/weeklyReport';
import { RadioButton } from 'components/form';
jest.mock('react-native-toast-message');
jest.mock('axios');
const mockAxios = axios as jest.Mocked<typeof axios>;
const mockedNavigate = jest.fn();
jest.mock('@react-navigation/native', () => {
return {
useNavigation: () => ({
reset: mockedNavigate,
}),
};
});
describe('WeeklyReport', () => {
const validFormValues: { [_: string]: any } = {
weight: '52',
height: '90',
waist_size: '190',
changes_felt: 1,
hunger_level: 1,
fullness_level: 1,
heavy_meal: 1,
snacks: 1,
sweet_beverages: 1,
sugary_ingredients: 1,
fried_snacks: 1,
umami_snacks: 1,
sweet_snacks: 1,
fruits_portion: 1,
vegetables_portion: 1,
water_consumption: '80',
physical_activity: [1],
physical_activity_other: '',
time_for_activity: 1,
feeling_rating: 1,
lesson_learned: 'hai',
problem_faced_and_feedbacks: 'feedback',
};
it('initially has disabled next button', () => {
const { getByText, queryByText } = render(<WeeklyReport />);
const weightTextField = queryByText(/Berat Badan/i);
expect(weightTextField).toBeTruthy();
const nextButton = getByText(/Lanjut/i);
expect(nextButton).toBeTruthy();
fireEvent.press(nextButton);
expect(queryByText(/Berat Badan/i)).toBeTruthy();
});
it('redirects to choose week for report if all form values are valid and submit success', async () => {
const createUserReportApi = () =>
Promise.resolve({
status: 201,
data: validFormValues,
});
mockAxios.request.mockImplementationOnce(createUserReportApi);
const { getByText, getByPlaceholderText, getByTestId } = render(
<WeeklyReport />,
);
dietReportTextFields.dietReportPage1.forEach(({ name, placeholder }) => {
const formField = getByPlaceholderText(placeholder as string);
fireEvent.changeText(formField, validFormValues[name]);
});
fireEvent.press(getByText(/Lanjut/i));
dietReportTextFields.dietReportPage2.forEach(({ name, placeholder }) => {
const formField = getByPlaceholderText(placeholder as string);
fireEvent.changeText(formField, validFormValues[name]);
});
dietReportSelectFields.dietReportPage2.forEach(({ name }) => {
const formField = getByTestId(name);
const firstChoice = formField.findAllByType(RadioButton)[0];
fireEvent.press(firstChoice);
});
fireEvent.press(getByText(/Lanjut/i));
dietReportSelectFields.dietReportPage3.forEach(({ name }) => {
const formField = getByTestId(name);
const firstChoice = formField.findAllByType(RadioButton)[0];
fireEvent.press(firstChoice);
});
fireEvent.press(getByText(/Lanjut/i));
dietReportSelectFields.dietReportPage4.forEach(({ choiceList }) => {
const firstChoice = getByText(choiceList[0]);
fireEvent.press(firstChoice);
});
dietReportTextFields.dietReportPage4.forEach(({ name, placeholder }) => {
const formField = getByPlaceholderText(placeholder as string);
fireEvent.changeText(formField, validFormValues[name]);
});
const submitButton = getByText('Selesai');
await waitFor(() => fireEvent.press(submitButton));
expect(mockedNavigate).toHaveBeenCalledTimes(1);
});
it('does not redirect to choose week for report if all form values are valid but submit fails', async () => {
const createUserReportApi = () =>
Promise.reject({
status: 400,
response: {
data: 'error',
},
});
mockAxios.request.mockImplementationOnce(createUserReportApi);
const { getByText, getByPlaceholderText, getByTestId } = render(
<WeeklyReport />,
);
dietReportTextFields.dietReportPage1.forEach(({ name, placeholder }) => {
const formField = getByPlaceholderText(placeholder as string);
fireEvent.changeText(formField, validFormValues[name]);
});
fireEvent.press(getByText(/Lanjut/i));
dietReportTextFields.dietReportPage2.forEach(({ name, placeholder }) => {
const formField = getByPlaceholderText(placeholder as string);
fireEvent.changeText(formField, validFormValues[name]);
});
dietReportSelectFields.dietReportPage2.forEach(({ name }) => {
const formField = getByTestId(name);
const firstChoice = formField.findAllByType(RadioButton)[0];
fireEvent.press(firstChoice);
});
fireEvent.press(getByText(/Lanjut/i));
dietReportSelectFields.dietReportPage3.forEach(({ name }) => {
const formField = getByTestId(name);
const firstChoice = formField.findAllByType(RadioButton)[0];
fireEvent.press(firstChoice);
});
fireEvent.press(getByText(/Lanjut/i));
dietReportSelectFields.dietReportPage4.forEach(({ choiceList }) => {
const firstChoice = getByText(choiceList[0]);
fireEvent.press(firstChoice);
});
dietReportTextFields.dietReportPage4.forEach(({ name, placeholder }) => {
const formField = getByPlaceholderText(placeholder as string);
fireEvent.changeText(formField, validFormValues[name]);
});
const submitButton = getByText('Selesai');
await waitFor(() => fireEvent.press(submitButton));
expect(mockedNavigate).toHaveBeenCalledTimes(1);
});
afterAll(() => {
jest.clearAllMocks();
});
});
import React, { FC, useContext, useState } from 'react';
import React, { FC, useState } from 'react';
import { useNavigation } from '@react-navigation/native';
import * as ROUTES from 'constants/routes';
import { WizardContainer, Toast, Loader } from 'components/core';
import { WizardContainer, Toast } from 'components/core';
import {
dietReportTextFields,
dietReportSelectFields,
} from 'constants/weeklyReport';
import { useApi, useForm } from 'hooks';
import { useForm } from 'hooks';
import { generateValidationSchema } from 'utils/form';
import { createUserReportApi, retrieveUserReportById } from 'services/progress';
import { createUserReportApi } from 'services/progress';
import { initialValues, fieldValidations, convertPayload } from './schema';
import { pages } from './components';
import { UserContext } from 'provider';
const WeeklyReport: FC = () => {
const [currentPage, setCurrentPage] = useState(1);
const { user } = useContext(UserContext);
const { isLoading, data } = useApi(() => retrieveUserReportById(user.id!));
const navigation = useNavigation();
const {
getTextInputProps,
getFormFieldProps,
isFormUntouched,
isFieldError,
handleSubmit,
isSubmitting,
values: formValues,
} = useForm({
initialValues,
validationSchema: generateValidationSchema(fieldValidations),
......@@ -49,28 +46,23 @@ const WeeklyReport: FC = () => {
});
const isCurrentPageError = (): boolean => {
if (currentPage === 1) {
return [
formValues.height,
formValues.weight,
formValues.waist_size,
].reduce((acc: boolean, item) => acc || item === '', false);
}
const fields = [
...(dietReportTextFields[`dietReportPage${currentPage}`] || []),
...(dietReportSelectFields[`dietReportPage${currentPage}`] || []),
...dietReportSelectFields[`dietReportPage${currentPage}`],
];
return (
isFormUntouched() ||
fields.reduce(
return fields.reduce(
(acc: boolean, item) => acc || isFieldError(item.name),
false,
)
);
};
console.log('diluar if');
if (isLoading) {
return <Loader />;
} else if (data?.length > 0) {
navigation.reset({
index: 0,
routes: [{ name: ROUTES.weeklyReportReadOnly, params: data }],
});
}
return (
<WizardContainer
......
......@@ -8,7 +8,7 @@ import {
NutritionistCommentResponse,
} from './models';
export const retrieveUserReportById = (
export const retrieveUserReportByIdApi = (
clientId: number,
): ApiResponse<UserReportResponse[]> => {
return api(RequestMethod.GET, apiUrls.userReportByClientId(clientId));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment