diff --git a/src/components/mui/__tests__/mui-formik-quantity-field.test.js b/src/components/mui/__tests__/mui-formik-quantity-field.test.js new file mode 100644 index 000000000..a73942773 --- /dev/null +++ b/src/components/mui/__tests__/mui-formik-quantity-field.test.js @@ -0,0 +1,68 @@ +import React from "react"; +import { render, screen, act } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import { Formik, Form } from "formik"; +import "@testing-library/jest-dom"; +import MuiFormikQuantityField from "../formik-inputs/mui-formik-quantity-field"; + +const renderWithFormik = (props, initialValues = { testField: [] }) => + render( + +
+ + + +
+ ); + +describe("MuiFormikQuantityField", () => { + it("must accept user input", async () => { + const onSubmit = jest.fn(); + + renderWithFormik({ + label: "some field", + onSubmit + }); + + const field = screen.getByLabelText("some field"); + expect(field).toBeInTheDocument(); + + const submitButton = screen.getByText("submit"); + await act(async () => { + await userEvent.type(field, "12345"); + await userEvent.click(submitButton); + }); + + expect(onSubmit).toHaveBeenCalledWith( + expect.objectContaining({ + testField: 12345 + }), + expect.anything() + ); + }); + + it("must filter invalid characters", async () => { + const onSubmit = jest.fn(); + + renderWithFormik({ + label: "some field", + onSubmit + }); + + const field = screen.getByLabelText("some field"); + expect(field).toBeInTheDocument(); + + const submitButton = screen.getByText("submit"); + await act(async () => { + await userEvent.type(field, "123eEe45"); + await userEvent.click(submitButton); + }); + + expect(onSubmit).toHaveBeenCalledWith( + expect.objectContaining({ + testField: 12345 + }), + expect.anything() + ); + }); +}); diff --git a/src/components/mui/formik-inputs/mui-formik-quantity-field.js b/src/components/mui/formik-inputs/mui-formik-quantity-field.js new file mode 100644 index 000000000..133716542 --- /dev/null +++ b/src/components/mui/formik-inputs/mui-formik-quantity-field.js @@ -0,0 +1,30 @@ +import React from "react"; +import PropTypes from "prop-types"; +import MuiFormikTextField from "./mui-formik-textfield"; + +const BLOCKED_KEYS = ["e", "E", "+", "-"]; + +const MuiFormikQuantityField = ({ ...props }) => ( + { + if (BLOCKED_KEYS.includes(e.key)) { + e.nativeEvent.preventDefault(); + e.nativeEvent.stopImmediatePropagation(); + } + }} + inputProps={{ + min: 0, + inputMode: "numeric" + }} + // eslint-disable-next-line react/jsx-props-no-spreading + {...props} + /> +); + +MuiFormikQuantityField.propTypes = { + name: PropTypes.string.isRequired, + label: PropTypes.string +}; + +export default MuiFormikQuantityField; diff --git a/src/pages/sponsors-global/form-templates/sponsor-inventory-popup.js b/src/pages/sponsors-global/form-templates/sponsor-inventory-popup.js index 9299b2325..f66bfd749 100644 --- a/src/pages/sponsors-global/form-templates/sponsor-inventory-popup.js +++ b/src/pages/sponsors-global/form-templates/sponsor-inventory-popup.js @@ -35,6 +35,7 @@ import { formMetafieldsValidation } from "../../../utils/yup"; import AdditionalInputList from "../../../components/mui/formik-inputs/additional-input/additional-input-list"; +import MuiFormikQuantityField from "../../../components/mui/formik-inputs/mui-formik-quantity-field"; const SponsorItemDialog = ({ open, @@ -226,7 +227,7 @@ const SponsorItemDialog = ({ {T.translate("edit_inventory_item.default_quantity")} - - {T.translate("edit_inventory_item.quantity_limit_per_show")} - ({ ...data }); @@ -41,7 +42,9 @@ const SponsorFormItemForm = ({ initialValues, onSubmit }) => { early_bird_rate: decimalValidation(), standard_rate: decimalValidation(), onsite_rate: decimalValidation(), - default_quantity: positiveNumberValidation(), + default_quantity: positiveNumberValidation().required( + T.translate("validation.required") + ), quantity_limit_per_sponsor: positiveNumberValidation(), quantity_limit_per_show: positiveNumberValidation(), meta_fields: formMetafieldsValidation() @@ -119,7 +122,7 @@ const SponsorFormItemForm = ({ initialValues, onSubmit }) => { /> - { /> - { /> -