Skip to content

Commit 513309c

Browse files
DmytroAlipovDima Alipov
andauthored
fix: no validation for combined length of org, number, run (#1262)
Co-authored-by: Dima Alipov <[email protected]>
1 parent bbe15af commit 513309c

5 files changed

Lines changed: 43 additions & 4 deletions

File tree

src/data/constants.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,7 @@ export const VisibilityTypes = /** @type {const} */ ({
5353
UNSCHEDULED: 'unscheduled',
5454
NEEDS_ATTENTION: 'needs_attention',
5555
});
56+
57+
export const TOTAL_LENGTH_KEY = 'total-length';
58+
59+
export const MAX_TOTAL_LENGTH = 65;

src/generic/create-or-rerun-course/CreateOrRerunCourseForm.jsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import TypeaheadDropdown from '../../editors/sharedComponents/TypeaheadDropdown'
1616

1717
import AlertMessage from '../alert-message';
1818
import { STATEFUL_BUTTON_STATES } from '../../constants';
19-
import { RequestStatus } from '../../data/constants';
19+
import { RequestStatus, TOTAL_LENGTH_KEY } from '../../data/constants';
2020
import { getSavingStatus } from '../data/selectors';
2121
import { getStudioHomeData } from '../../studio-home/data/selectors';
2222
import { updatePostErrors } from '../data/slice';
@@ -132,6 +132,8 @@ const CreateOrRerunCourseForm = ({
132132
},
133133
];
134134

135+
const errorMessage = errors[TOTAL_LENGTH_KEY] || postErrors?.errMsg;
136+
135137
const createButtonState = {
136138
labels: {
137139
default: intl.formatMessage(isCreateNewCourse ? messages.createButton : messages.rerunCreateButton),
@@ -202,11 +204,11 @@ const CreateOrRerunCourseForm = ({
202204
return (
203205
<div className="create-or-rerun-course-form">
204206
<TransitionReplace>
205-
{showErrorBanner ? (
207+
{(errors[TOTAL_LENGTH_KEY] || showErrorBanner) ? (
206208
<AlertMessage
207209
variant="danger"
208210
icon={InfoIcon}
209-
title={postErrors.errMsg}
211+
title={errorMessage}
210212
aria-hidden="true"
211213
aria-labelledby={intl.formatMessage(
212214
messages.alertErrorExistsAriaLabelledBy,

src/generic/create-or-rerun-course/CreateOrRerunCourseForm.test.jsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,28 @@ describe('<CreateOrRerunCourseForm />', () => {
192192
expect(rerunBtn).toBeDisabled();
193193
});
194194

195+
it('shows error message when total length exceeds 65 characters', async () => {
196+
const updatedProps = {
197+
...props,
198+
initialValues: {
199+
displayName: 'Long Title Course',
200+
org: 'long-org',
201+
number: 'number',
202+
run: '2024',
203+
},
204+
};
205+
206+
render(<RootWrapper {...updatedProps} />);
207+
await mockStore();
208+
const numberInput = screen.getByPlaceholderText(messages.courseNumberPlaceholder.defaultMessage);
209+
210+
fireEvent.change(numberInput, { target: { value: 'long-name-which-is-longer-than-65-characters-to-check-for-errors' } });
211+
212+
waitFor(() => {
213+
expect(screen.getByText(messages.totalLengthError)).toBeInTheDocument();
214+
});
215+
});
216+
195217
it('should be disabled create button if form has error', async () => {
196218
render(<RootWrapper {...props} />);
197219
await mockStore();

src/generic/create-or-rerun-course/hooks.jsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import * as Yup from 'yup';
66
import { useNavigate } from 'react-router-dom';
77

88
import { REGEX_RULES } from '../../constants';
9-
import { RequestStatus } from '../../data/constants';
9+
import { RequestStatus, MAX_TOTAL_LENGTH, TOTAL_LENGTH_KEY } from '../../data/constants';
1010
import { getStudioHomeData } from '../../studio-home/data/selectors';
1111
import {
1212
getRedirectUrlObj,
@@ -60,6 +60,12 @@ const useCreateOrRerunCourse = (initialValues) => {
6060
intl.formatMessage(messages.disallowedCharsError),
6161
)
6262
.matches(noSpaceRule, intl.formatMessage(messages.noSpaceError)),
63+
}).test(TOTAL_LENGTH_KEY, intl.formatMessage(messages.totalLengthError), function validateTotalLength() {
64+
const { org, number, run } = this?.options.originalValue || {};
65+
if ((org?.length || 0) + (number?.length || 0) + (run?.length || 0) > MAX_TOTAL_LENGTH) {
66+
return this.createError({ path: TOTAL_LENGTH_KEY, message: intl.formatMessage(messages.totalLengthError) });
67+
}
68+
return true;
6369
});
6470

6571
const {

src/generic/create-or-rerun-course/messages.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { defineMessages } from '@edx/frontend-platform/i18n';
2+
import { MAX_TOTAL_LENGTH } from '../../data/constants';
23

34
const messages = defineMessages({
45
courseDisplayNameLabel: {
@@ -117,6 +118,10 @@ const messages = defineMessages({
117118
id: 'course-authoring.create-or-rerun-course.no-space.error',
118119
defaultMessage: 'Please do not use any spaces in this field.',
119120
},
121+
totalLengthError: {
122+
id: 'course-authoring.create-or-rerun-course.total-length-error.error',
123+
defaultMessage: `The combined length of the organization, course number and course run fields cannot be more than ${MAX_TOTAL_LENGTH} characters.`,
124+
},
120125
alertErrorExistsAriaLabelledBy: {
121126
id: 'course-authoring.create-or-rerun-course.error.already-exists.labelledBy',
122127
defaultMessage: 'alert-already-exists-title',

0 commit comments

Comments
 (0)