Просмотр исходного кода

fix(settings): Manually call blur in booleanField, save usage setting (#36550)

Fixes the boolean field for Usage Statistics in admin settings
Scott Cooper 2 лет назад
Родитель
Сommit
ec2e5f35b3

+ 8 - 1
static/app/components/forms/controls/radioBoolean.tsx

@@ -11,17 +11,20 @@ type OptionProps = {
   checked?: boolean;
   disabled?: boolean;
   name?: string;
+  onBlur?: (event: React.ChangeEvent<HTMLInputElement>) => void;
   onChange?: OnChangeHandler;
 };
 
 const Option = forwardRef(function Option(
-  {name, disabled, label, value, checked, onChange}: OptionProps,
+  {name, disabled, label, value, checked, onChange, onBlur}: OptionProps,
   ref: React.Ref<HTMLInputElement>
 ) {
   function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
     const isTrue = e.target.value === 'true';
 
     onChange?.(isTrue, e);
+    // Manually trigger blur to trigger saving on change
+    onBlur?.(e);
   }
 
   return (
@@ -46,6 +49,7 @@ type Props = {
   disabled?: boolean;
   name?: string;
   noLabel?: string;
+  onBlur?: (event: React.ChangeEvent<HTMLInputElement>) => void;
   onChange?: OnChangeHandler;
   value?: boolean;
   yesFirst?: boolean;
@@ -57,6 +61,7 @@ const RadioBoolean = forwardRef(function RadioBoolean(
     disabled,
     name,
     onChange,
+    onBlur,
     value,
     yesFirst = true,
     yesLabel = 'Yes',
@@ -73,6 +78,7 @@ const RadioBoolean = forwardRef(function RadioBoolean(
       disabled={disabled}
       label={yesLabel}
       onChange={onChange}
+      onBlur={onBlur}
     />
   );
   const noOption = (
@@ -83,6 +89,7 @@ const RadioBoolean = forwardRef(function RadioBoolean(
       disabled={disabled}
       label={noLabel}
       onChange={onChange}
+      onBlur={onBlur}
     />
   );
 

+ 43 - 41
tests/js/spec/components/deprecatedforms/radioBooleanField.spec.jsx

@@ -1,49 +1,51 @@
-import {mountWithTheme} from 'sentry-test/enzyme';
+import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
 
 import {Form, RadioBooleanField} from 'sentry/components/deprecatedforms';
 import NewRadioBooleanField from 'sentry/components/forms/radioBooleanField';
 
 describe('RadioBooleanField', function () {
-  describe('render()', function () {
-    it('renders without form context', function () {
-      const wrapper = mountWithTheme(
+  it('renders without form context', function () {
+    const wrapper = render(
+      <RadioBooleanField name="fieldName" yesLabel="Yes" noLabel="No" />
+    );
+    expect(wrapper.container).toSnapshot();
+  });
+
+  it('renders with form context', function () {
+    const wrapper = render(
+      <Form initialData={{fieldName: true}}>
         <RadioBooleanField name="fieldName" yesLabel="Yes" noLabel="No" />
-      );
-      expect(wrapper).toSnapshot();
-    });
-
-    it('renders with form context', function () {
-      const wrapper = mountWithTheme(
-        <Form initialData={{fieldName: true}}>
-          <RadioBooleanField name="fieldName" yesLabel="Yes" noLabel="No" />
-        </Form>
-      );
-      expect(wrapper).toSnapshot();
-    });
-
-    it('renders new field without form context', function () {
-      const wrapper = mountWithTheme(
-        <NewRadioBooleanField name="fieldName" yesLabel="Yes" noLabel="No" />
-      );
-      expect(wrapper).toSnapshot();
-    });
-
-    it('can change values', function () {
-      const mock = jest.fn();
-      const wrapper = mountWithTheme(
-        <NewRadioBooleanField
-          onChange={mock}
-          name="fieldName"
-          yesLabel="Yes"
-          noLabel="No"
-        />
-      );
-
-      wrapper.find('input[value="true"]').simulate('change');
-      expect(mock).toHaveBeenCalledWith(true, expect.anything());
-
-      wrapper.find('input[value="false"]').simulate('change');
-      expect(mock).toHaveBeenCalledWith(false, expect.anything());
-    });
+      </Form>
+    );
+    expect(wrapper.container).toSnapshot();
+  });
+
+  it('renders new field without form context', function () {
+    const wrapper = render(
+      <NewRadioBooleanField name="fieldName" yesLabel="Yes" noLabel="No" />
+    );
+    expect(wrapper.container).toSnapshot();
+  });
+
+  it('can change values', function () {
+    const changeMock = jest.fn();
+    const blurMock = jest.fn();
+    render(
+      <NewRadioBooleanField
+        onChange={changeMock}
+        onBlur={blurMock}
+        name="fieldName"
+        yesLabel="Yes"
+        noLabel="No"
+      />
+    );
+
+    userEvent.click(screen.getByRole('radio', {name: 'Yes'}));
+    expect(changeMock).toHaveBeenCalledWith(true, expect.anything());
+
+    userEvent.click(screen.getByRole('radio', {name: 'No'}));
+    expect(changeMock).toHaveBeenCalledWith(false, expect.anything());
+
+    expect(blurMock).toHaveBeenCalledTimes(2);
   });
 });