fix: no validation for combined length of org, number, run (#1261)
Co-authored-by: Dima Alipov <dimaalipov@192.168.1.101>
This commit is contained in:
@@ -53,3 +53,7 @@ export const VisibilityTypes = /** @type {const} */ ({
|
||||
UNSCHEDULED: 'unscheduled',
|
||||
NEEDS_ATTENTION: 'needs_attention',
|
||||
});
|
||||
|
||||
export const TOTAL_LENGTH_KEY = 'total-length';
|
||||
|
||||
export const MAX_TOTAL_LENGTH = 65;
|
||||
|
||||
@@ -16,7 +16,7 @@ import { TypeaheadDropdown } from '@edx/frontend-lib-content-components';
|
||||
|
||||
import AlertMessage from '../alert-message';
|
||||
import { STATEFUL_BUTTON_STATES } from '../../constants';
|
||||
import { RequestStatus } from '../../data/constants';
|
||||
import { RequestStatus, TOTAL_LENGTH_KEY } from '../../data/constants';
|
||||
import { getSavingStatus } from '../data/selectors';
|
||||
import { getStudioHomeData } from '../../studio-home/data/selectors';
|
||||
import { updatePostErrors } from '../data/slice';
|
||||
@@ -132,6 +132,8 @@ const CreateOrRerunCourseForm = ({
|
||||
},
|
||||
];
|
||||
|
||||
const errorMessage = errors[TOTAL_LENGTH_KEY] || postErrors?.errMsg;
|
||||
|
||||
const createButtonState = {
|
||||
labels: {
|
||||
default: intl.formatMessage(isCreateNewCourse ? messages.createButton : messages.rerunCreateButton),
|
||||
@@ -202,11 +204,11 @@ const CreateOrRerunCourseForm = ({
|
||||
return (
|
||||
<div className="create-or-rerun-course-form">
|
||||
<TransitionReplace>
|
||||
{showErrorBanner ? (
|
||||
{(errors[TOTAL_LENGTH_KEY] || showErrorBanner) ? (
|
||||
<AlertMessage
|
||||
variant="danger"
|
||||
icon={InfoIcon}
|
||||
title={postErrors.errMsg}
|
||||
title={errorMessage}
|
||||
aria-hidden="true"
|
||||
aria-labelledby={intl.formatMessage(
|
||||
messages.alertErrorExistsAriaLabelledBy,
|
||||
|
||||
@@ -198,6 +198,30 @@ describe('<CreateOrRerunCourseForm />', () => {
|
||||
expect(rerunBtn).toBeDisabled();
|
||||
});
|
||||
|
||||
it('shows error message when total length exceeds 65 characters', async () => {
|
||||
const updatedProps = {
|
||||
...props,
|
||||
initialValues: {
|
||||
displayName: 'Long Title Course',
|
||||
org: 'long-org',
|
||||
number: 'number',
|
||||
run: '2024',
|
||||
},
|
||||
};
|
||||
|
||||
render(<RootWrapper {...updatedProps} />);
|
||||
await mockStore();
|
||||
const numberInput = screen.getByPlaceholderText(messages.courseNumberPlaceholder.defaultMessage);
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.change(numberInput, { target: { value: 'long-name-which-is-longer-than-65-characters-to-check-for-errors' } });
|
||||
});
|
||||
|
||||
waitFor(() => {
|
||||
expect(screen.getByText(messages.totalLengthError)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('should be disabled create button if form has error', async () => {
|
||||
render(<RootWrapper {...props} />);
|
||||
await mockStore();
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useIntl } from '@edx/frontend-platform/i18n';
|
||||
import { useFormik } from 'formik';
|
||||
import * as Yup from 'yup';
|
||||
|
||||
import { RequestStatus } from '../../data/constants';
|
||||
import { RequestStatus, MAX_TOTAL_LENGTH, TOTAL_LENGTH_KEY } from '../../data/constants';
|
||||
import { getStudioHomeData } from '../../studio-home/data/selectors';
|
||||
import {
|
||||
getRedirectUrlObj,
|
||||
@@ -58,6 +58,12 @@ const useCreateOrRerunCourse = (initialValues) => {
|
||||
intl.formatMessage(messages.disallowedCharsError),
|
||||
)
|
||||
.matches(noSpaceRule, intl.formatMessage(messages.noSpaceError)),
|
||||
}).test(TOTAL_LENGTH_KEY, intl.formatMessage(messages.totalLengthError), function validateTotalLength() {
|
||||
const { org, number, run } = this?.options.originalValue || {};
|
||||
if ((org?.length || 0) + (number?.length || 0) + (run?.length || 0) > MAX_TOTAL_LENGTH) {
|
||||
return this.createError({ path: TOTAL_LENGTH_KEY, message: intl.formatMessage(messages.totalLengthError) });
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
const {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { defineMessages } from '@edx/frontend-platform/i18n';
|
||||
import { MAX_TOTAL_LENGTH } from '../../data/constants';
|
||||
|
||||
const messages = defineMessages({
|
||||
courseDisplayNameLabel: {
|
||||
@@ -117,6 +118,10 @@ const messages = defineMessages({
|
||||
id: 'course-authoring.create-or-rerun-course.no-space.error',
|
||||
defaultMessage: 'Please do not use any spaces in this field.',
|
||||
},
|
||||
totalLengthError: {
|
||||
id: 'course-authoring.create-or-rerun-course.total-length-error.error',
|
||||
defaultMessage: `The combined length of the organization, course number and course run fields cannot be more than ${MAX_TOTAL_LENGTH} characters.`,
|
||||
},
|
||||
alertErrorExistsAriaLabelledBy: {
|
||||
id: 'course-authoring.create-or-rerun-course.error.already-exists.labelledBy',
|
||||
defaultMessage: 'alert-already-exists-title',
|
||||
|
||||
Reference in New Issue
Block a user