From 7513e469942b06f8ff63fef47264f59fa63f24ec Mon Sep 17 00:00:00 2001 From: Ali Nawaz Date: Mon, 19 Dec 2022 13:40:00 +0500 Subject: [PATCH] fix: fix failing tests and linting errors and update snapshots --- .../CreateCoursePage/CreateCourseForm.jsx | 33 ++-- .../CreateCourseForm.test.jsx.snap | 180 +++++++++++++++++- .../CreateCoursePage.test.jsx.snap | 116 ++++++----- src/components/CreateCoursePage/index.jsx | 7 +- src/components/DateTimeField/index.jsx | 4 + .../__snapshots__/PriceList.test.jsx.snap | 22 +++ src/components/PriceList/index.jsx | 7 +- src/utils/validation.js | 71 +++---- src/utils/validation.test.js | 2 +- 9 files changed, 317 insertions(+), 125 deletions(-) diff --git a/src/components/CreateCoursePage/CreateCourseForm.jsx b/src/components/CreateCoursePage/CreateCourseForm.jsx index 180c06933..d1dadb4c8 100644 --- a/src/components/CreateCoursePage/CreateCourseForm.jsx +++ b/src/components/CreateCoursePage/CreateCourseForm.jsx @@ -14,8 +14,8 @@ import PriceList from '../PriceList'; import { DATE_INPUT_PATTERN, } from '../../data/constants'; -import { - clearCourseInfoErrors, clearCreateCourseStatus +import { + clearCourseInfoErrors, clearCreateCourseStatus, } from '../../data/actions/courseInfo'; import { @@ -26,11 +26,10 @@ import { isSafari, localTimeZone, getDateWithDashes, getOptionsData, parseCourseTypeOptions, parseOptions, } from '../../utils'; -import { - handleCourseCreateFail, requiredValidate, dateTimeValidate, courseRunKeyValidate +import { + handleCourseCreateFail, requiredValidate, dateTimeValidate, courseRunKeyValidate, } from '../../utils/validation'; - class BaseCreateCourseForm extends React.Component { constructor(props) { super(props); @@ -116,7 +115,7 @@ class BaseCreateCourseForm extends React.Component { component={RenderSelectField} props={ { - name: 'org' + name: 'org', } } options={this.processOrganizations(organizations)} @@ -129,7 +128,7 @@ class BaseCreateCourseForm extends React.Component { component={RenderInputTextField} props={ { - name: 'title' + name: 'title', } } type="text" @@ -150,7 +149,7 @@ class BaseCreateCourseForm extends React.Component { component={RenderInputTextField} props={ { - name: 'number' + name: 'number', } } type="text" @@ -195,7 +194,7 @@ class BaseCreateCourseForm extends React.Component { component={RenderSelectField} props={ { - name: 'type' + name: 'type', } } options={courseTypeOptions} @@ -222,7 +221,7 @@ class BaseCreateCourseForm extends React.Component { component={RenderInputTextField} props={ { - name: 'courseRunKey' + name: 'courseRunKey', } } type="text" @@ -249,7 +248,7 @@ class BaseCreateCourseForm extends React.Component { component={DateTimeField} props={ { - name: 'start' + name: 'start', } } dateLabel="Start date" @@ -267,7 +266,7 @@ class BaseCreateCourseForm extends React.Component { component={DateTimeField} props={ { - name: 'end' + name: 'end', } } dateLabel="End date" @@ -290,7 +289,7 @@ class BaseCreateCourseForm extends React.Component { component={DateTimeField} props={ { - name: 'start' + name: 'start', } } dateLabel="Start date" @@ -306,7 +305,7 @@ class BaseCreateCourseForm extends React.Component { component={DateTimeField} props={ { - name: 'end' + name: 'end', } } dateLabel="End date" @@ -323,7 +322,7 @@ class BaseCreateCourseForm extends React.Component { component={RenderSelectField} props={ { - name: 'run_type' + name: 'run_type', } } options={currentFormValues.type ? courseRunTypeOptions[currentFormValues.type] : [{ label: 'Select Course enrollment track first', value: '' }]} @@ -344,7 +343,7 @@ class BaseCreateCourseForm extends React.Component { component={RenderSelectField} props={ { - name: 'pacing_type' + name: 'pacing_type', } } options={pacingTypeOptions} @@ -426,6 +425,6 @@ BaseCreateCourseForm.propTypes = { export default reduxForm({ form: 'create-course-form', - onSubmitFail: handleCourseCreateFail + onSubmitFail: handleCourseCreateFail, })(BaseCreateCourseForm); export { BaseCreateCourseForm }; diff --git a/src/components/CreateCoursePage/__snapshots__/CreateCourseForm.test.jsx.snap b/src/components/CreateCoursePage/__snapshots__/CreateCourseForm.test.jsx.snap index 5e12c18ab..83739da7c 100644 --- a/src/components/CreateCoursePage/__snapshots__/CreateCourseForm.test.jsx.snap +++ b/src/components/CreateCoursePage/__snapshots__/CreateCourseForm.test.jsx.snap @@ -9,6 +9,7 @@ exports[`CreateCourseForm renders html correctly while submitting 1`] = `
} name="title" + props={ + Object { + "name": "title", + } + } required={true} type="text" + validate={[Function]} /> } name="number" - required={true} + props={ + Object { + "name": "number", + } + } type="text" + validate={[Function]} />
} name="title" + props={ + Object { + "name": "title", + } + } required={true} type="text" + validate={[Function]} /> } name="number" - required={true} + props={ + Object { + "name": "number", + } + } type="text" + validate={[Function]} />
} name="title" + props={ + Object { + "name": "title", + } + } required={true} type="text" + validate={[Function]} /> } name="number" - required={true} + props={ + Object { + "name": "number", + } + } type="text" + validate={[Function]} />
+ + Fail +
+
- - Fail -
-
@@ -209,7 +213,9 @@ exports[`CreateCoursePage renders page correctly with course create in progress initialValues={Object {}} isCreating={true} keepDirtyOnReinitialize={false} + onChange={[Function]} onSubmit={[Function]} + onSubmitFail={[Function]} organizations={ Array [ Object { @@ -274,7 +280,9 @@ exports[`CreateCoursePage renders page correctly with course create success 1`] initialValues={Object {}} isCreating={false} keepDirtyOnReinitialize={false} + onChange={[Function]} onSubmit={[Function]} + onSubmitFail={[Function]} organizations={ Array [ Object { @@ -368,6 +376,32 @@ exports[`CreateCoursePage renders page correctly with org error 1`] = ` wide={false} >
+ + Fail +
+
- - Fail -
-
@@ -472,7 +482,9 @@ exports[`CreateCoursePage renders page correctly with organizations 1`] = ` initialValues={Object {}} isCreating={false} keepDirtyOnReinitialize={false} + onChange={[Function]} onSubmit={[Function]} + onSubmitFail={[Function]} organizations={ Array [ Object { diff --git a/src/components/CreateCoursePage/index.jsx b/src/components/CreateCoursePage/index.jsx index 9840ee707..05761644a 100644 --- a/src/components/CreateCoursePage/index.jsx +++ b/src/components/CreateCoursePage/index.jsx @@ -35,11 +35,10 @@ class CreateCoursePage extends React.Component { this.setStartedFetching(); } - componentDidUpdate(prevProps, prevState) { + componentDidUpdate(prevProps) { // check if errors on form submission and scroll to them - if (this.props.courseInfo.error && (! prevProps.courseInfo || !prevProps.courseInfo.error)){ - window.scrollTo(0, 0) - + if (this.props.courseInfo.error && (!prevProps.courseInfo || !prevProps.courseInfo.error)) { + window.scrollTo(0, 0); } } diff --git a/src/components/DateTimeField/index.jsx b/src/components/DateTimeField/index.jsx index 387b02d91..740791063 100644 --- a/src/components/DateTimeField/index.jsx +++ b/src/components/DateTimeField/index.jsx @@ -161,6 +161,10 @@ DateTimeField.propTypes = { type: PropTypes.string, pattern: PropTypes.string, placeholder: PropTypes.string, + meta: PropTypes.shape({ + touched: PropTypes.bool, + error: PropTypes.string, + }).isRequired, }; DateTimeField.defaultProps = { diff --git a/src/components/PriceList/__snapshots__/PriceList.test.jsx.snap b/src/components/PriceList/__snapshots__/PriceList.test.jsx.snap index f74efa55d..8e45751d3 100644 --- a/src/components/PriceList/__snapshots__/PriceList.test.jsx.snap +++ b/src/components/PriceList/__snapshots__/PriceList.test.jsx.snap @@ -25,8 +25,19 @@ exports[`PriceList renders with price labels 1`] = ` /> } name="prices.a" + props={ + Object { + "name": "prices.a", + } + } required={false} type="number" + validate={ + Array [ + [Function], + [Function], + ] + } /> } name="prices.b" + props={ + Object { + "name": "prices.b", + } + } required={false} type="number" + validate={ + Array [ + [Function], + [Function], + ] + } /> `; diff --git a/src/components/PriceList/index.jsx b/src/components/PriceList/index.jsx index 3b351a412..5f8ce72c7 100644 --- a/src/components/PriceList/index.jsx +++ b/src/components/PriceList/index.jsx @@ -5,11 +5,10 @@ import { Field } from 'redux-form'; import RenderInputTextField from '../RenderInputTextField'; import FieldLabel from '../FieldLabel'; -import { - requiredValidate, priceValidate, noValidate +import { + requiredValidate, priceValidate, noValidate, } from '../../utils/validation'; - const PriceList = ({ disabled, extraInput, @@ -24,7 +23,7 @@ const PriceList = ({ component={RenderInputTextField} props={ { - name: `prices.${seatType}` + name: `prices.${seatType}`, } } extraInput={{ diff --git a/src/utils/validation.js b/src/utils/validation.js index 4539d23d5..20706b8db 100644 --- a/src/utils/validation.js +++ b/src/utils/validation.js @@ -3,66 +3,58 @@ import moment from 'moment'; import store from '../data/store'; import { jsonDeepCopy } from '.'; import { courseSubmittingFailure } from '../data/actions/courseSubmitInfo'; -import { PUBLISHED } from '../data/constants'; -import { DATE_FORMAT } from '../data/constants'; - +import { PUBLISHED, DATE_FORMAT } from '../data/constants'; const requiredMessage = 'This field is required'; // Dummy Validator: every input is valid -const noValidate = value => { - return undefined -} +const noValidate = () => undefined; // ensure that input is non-empty const requiredValidate = (value) => { - if (value !== undefined && value !== null && value !== ''){ - return undefined + if (value !== undefined && value !== null && value !== '') { + return undefined; } - return requiredMessage -} + return requiredMessage; +}; // ensure that the input is a valid datetime string in the format of DATE_FORMAT const dateTimeValidate = value => { - - let dateTime = moment(value, DATE_FORMAT, true) - if (dateTime.isValid()){ - return undefined + const dateTime = moment(value, DATE_FORMAT, true); + if (dateTime.isValid()) { + return undefined; } - return 'Please enter a valid date' -} - + return 'Please enter a valid date'; +}; const courseRunKeyValidate = value => { - let pattern=/^[a-zA-Z0-9-]*$/ - if (pattern.test(value)){ - return undefined + const pattern = /^[a-zA-Z0-9-]*$/; + if (pattern.test(value)) { + return undefined; } - return 'Please Enter a valid course key' -} + return 'Please Enter a valid course key'; +}; // validate a course price (price lies from 1 to 1000 and is a valid number of cents) const priceValidate = value => { + const pattern = /^[0-9]+(\.)?[0-9]{0,2}$/; - let pattern = /^[0-9]+(\.)?[0-9]{0,2}$/ - - if (! pattern.test(value)){ - return 'Please enter a valid price(with at most 2 decimal digits)' + if (!pattern.test(value)) { + return 'Please enter a valid price(with at most 2 decimal digits)'; } - let price = parseFloat(value) + const price = parseFloat(value); - if (Number.isNaN(price)){ - return 'Please enter a valid price' + if (Number.isNaN(price)) { + return 'Please enter a valid price'; } - - if (price < 1 || price > 1000){ - return 'Price should be between 1 and 1000(endpoints inclusive)' + if (price < 1 || price > 1000) { + return 'Price should be between 1 and 1000(endpoints inclusive)'; } - return undefined -} + return undefined; +}; // Basic validation that ensures some value was entered const basicValidate = value => (value ? undefined : requiredMessage); @@ -116,8 +108,8 @@ const getFieldName = (errors) => { } // Handle nested redux-form field names - if (otherInfo.constructor == Object){ - fieldName = fieldName + '.' + getFieldName(otherInfo) + if (otherInfo.constructor === Object) { + fieldName = `${fieldName}.${getFieldName(otherInfo)}`; } return fieldName; @@ -139,12 +131,9 @@ const handleCourseEditFail = (errors) => { const handleCourseCreateFail = (errors) => { const fieldName = getFieldName(errors); if (fieldName) { + const node = document.getElementsByName(fieldName)[0]; - let node = document.getElementsByName(fieldName)[0] - - if (node) - node.scrollIntoView({behavior: "smooth"}); - + if (node) { node.scrollIntoView({ behavior: 'smooth' }); } } }; diff --git a/src/utils/validation.test.js b/src/utils/validation.test.js index 34df8ab12..d7f97dbf1 100644 --- a/src/utils/validation.test.js +++ b/src/utils/validation.test.js @@ -50,7 +50,7 @@ describe('getFieldName', () => { ], full_description: 'This field is required', }; - expect(getFieldName(errors)).toEqual('course_runs[1].transcript_languages'); + expect(getFieldName(errors)).toEqual('course_runs[1].transcript_languages._error'); }); it('returns the first full field name in errors for deeply nested fields', () => {