"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.testControlledUnControlled = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
var React = _interopRequireWildcard(require("react"));
var _chai = require("chai");
var _sinon = require("sinon");
var _utils = require("@mui/monorepo/test/utils");
var _InputBase = require("@mui/material/InputBase");
var _pickers = require("test/utils/pickers");
var _jsxRuntime = require("react/jsx-runtime");
const _excluded = ["render", "renderWithProps", "values", "componentFamily", "emptyValue", "assertRenderedValue", "setNewValue", "clock"];
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
const testControlledUnControlled = (ElementToTest, options) => {
  const {
      render,
      renderWithProps,
      values,
      componentFamily,
      emptyValue,
      assertRenderedValue,
      setNewValue,
      clock
    } = options,
    pickerParams = (0, _objectWithoutPropertiesLoose2.default)(options, _excluded);
  const params = pickerParams;
  describe('Controlled / uncontrolled value', () => {
    it('should render `props.defaultValue` if no `props.value` is passed', () => {
      render( /*#__PURE__*/(0, _jsxRuntime.jsx)(ElementToTest, {
        defaultValue: values[0]
      }));
      assertRenderedValue(values[0]);
    });
    it('should render `props.value` if passed', () => {
      render( /*#__PURE__*/(0, _jsxRuntime.jsx)(ElementToTest, {
        value: values[0]
      }));
      assertRenderedValue(values[0]);
    });
    it('should render `props.value` if both `props.defaultValue` and `props.value` are passed', () => {
      render( /*#__PURE__*/(0, _jsxRuntime.jsx)(ElementToTest, {
        defaultValue: values[0],
        value: values[1]
      }));
      assertRenderedValue(values[1]);
    });
    it('should render nothing if neither `props.defaultValue` or `props.value` are passed', () => {
      render( /*#__PURE__*/(0, _jsxRuntime.jsx)(ElementToTest, {}));
      assertRenderedValue(emptyValue);
    });
    it('should call onChange when updating a value defined with `props.defaultValue` and update the rendered value', () => {
      const onChange = (0, _sinon.spy)();
      const {
        selectSection
      } = renderWithProps({
        defaultValue: values[0],
        onChange
      });
      const newValue = setNewValue(values[0], {
        selectSection
      });
      assertRenderedValue(newValue);
      // TODO: Clean this exception or change the clock behavior
      (0, _chai.expect)(onChange.callCount).to.equal((0, _pickers.getExpectedOnChangeCount)(componentFamily, params));
      if (Array.isArray(newValue)) {
        newValue.forEach((value, index) => {
          (0, _chai.expect)(onChange.lastCall.args[0][index]).toEqualDateTime(value);
        });
      } else {
        (0, _chai.expect)(onChange.lastCall.args[0]).toEqualDateTime(newValue);
      }
    });
    it('should call onChange when updating a value defined with `props.value`', () => {
      const onChange = (0, _sinon.spy)();
      const useControlledElement = props => {
        const [value, setValue] = React.useState(props?.value || null);
        const handleChange = React.useCallback(newValue => {
          setValue(newValue);
          props?.onChange(newValue);
        }, [props]);
        return {
          value,
          onChange: handleChange
        };
      };
      const {
        selectSection
      } = renderWithProps({
        value: values[0],
        onChange
      }, useControlledElement);
      const newValue = setNewValue(values[0], {
        selectSection
      });
      (0, _chai.expect)(onChange.callCount).to.equal((0, _pickers.getExpectedOnChangeCount)(componentFamily, params));
      if (Array.isArray(newValue)) {
        newValue.forEach((value, index) => {
          (0, _chai.expect)(onChange.lastCall.args[0][index]).toEqualDateTime(value);
        });
      } else {
        (0, _chai.expect)(onChange.lastCall.args[0]).toEqualDateTime(newValue);
      }
    });
    it('should react to `props.value` update', () => {
      const {
        setProps
      } = render( /*#__PURE__*/(0, _jsxRuntime.jsx)(ElementToTest, {
        value: values[0]
      }));
      setProps({
        value: values[1]
      });
      assertRenderedValue(values[1]);
    });
    ['readOnly', 'disabled'].forEach(prop => {
      it(`should apply ${prop}="true" prop`, () => {
        if (!['field', 'picker'].includes(componentFamily)) {
          return;
        }
        const handleChange = (0, _sinon.spy)();
        render( /*#__PURE__*/(0, _jsxRuntime.jsx)(ElementToTest, {
          value: values[0],
          onChange: handleChange,
          [prop]: true
        }));
        const textBoxes = _utils.screen.getAllByRole('textbox');
        textBoxes.forEach(textbox => {
          (0, _chai.expect)(textbox).to.have.attribute(prop.toLowerCase());
        });
      });
    });
    it('should not allow editing with keyboard in mobile pickers', () => {
      if (componentFamily !== 'picker' || params.variant !== 'mobile') {
        return;
      }
      const handleChange = (0, _sinon.spy)();
      render( /*#__PURE__*/(0, _jsxRuntime.jsx)(ElementToTest, {
        defaultValue: values[0],
        onChange: handleChange
      }));
      const input = _utils.screen.getAllByRole('textbox')[0];
      (0, _utils.act)(() => {
        input.focus();
      });
      clock.runToLast();
      _utils.userEvent.keyPress(input, {
        key: 'ArrowUp'
      });
      clock.runToLast();
      (0, _chai.expect)(handleChange.callCount).to.equal(0);
    });
    it('should have correct labelledby relationship when toolbar is shown', () => {
      if (componentFamily !== 'picker' || params.variant === 'desktop' && params.type === 'date-range') {
        return;
      }
      render( /*#__PURE__*/(0, _jsxRuntime.jsx)(ElementToTest, {
        open: true,
        slotProps: {
          toolbar: {
            hidden: false
          }
        },
        localeText: {
          toolbarTitle: 'Test toolbar'
        }
      }));
      (0, _chai.expect)(_utils.screen.getByLabelText('Test toolbar')).to.have.attribute('role', 'dialog');
    });
    it('should have correct labelledby relationship with provided label when toolbar is hidden', () => {
      if (componentFamily !== 'picker' || params.variant === 'desktop' && params.type === 'date-range') {
        return;
      }
      render( /*#__PURE__*/(0, _jsxRuntime.jsx)(ElementToTest, (0, _extends2.default)({
        open: true
      }, params.type === 'date-range' ? {
        localeText: {
          start: 'test',
          end: 'relationship'
        }
      } : {
        label: 'test relationship'
      }, {
        slotProps: {
          toolbar: {
            hidden: true
          }
        }
      })));
      (0, _chai.expect)(_utils.screen.getByLabelText('test relationship', {
        selector: 'div'
      })).to.have.attribute('role', 'dialog');
    });
    it('should have correct labelledby relationship without label and hidden toolbar but external props', () => {
      if (componentFamily !== 'picker' || params.variant === 'desktop' && params.type === 'date-range') {
        return;
      }
      render( /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
        children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
          id: "label-id",
          children: "external label"
        }), /*#__PURE__*/(0, _jsxRuntime.jsx)(ElementToTest, (0, _extends2.default)({
          open: true
        }, params.type === 'date-range' && {
          localeText: {
            start: '',
            end: ''
          }
        }, {
          slotProps: {
            toolbar: {
              hidden: true
            },
            [params.variant === 'desktop' ? 'popper' : 'mobilePaper']: {
              'aria-labelledby': 'label-id'
            }
          }
        }))]
      }));
      (0, _chai.expect)(_utils.screen.getByLabelText('external label')).to.have.attribute('role', 'dialog');
    });
    describe('slots: textField', () => {
      it('should respect provided `error="true"` prop', () => {
        if (!['field', 'picker'].includes(componentFamily)) {
          return;
        }
        render( /*#__PURE__*/(0, _jsxRuntime.jsx)(ElementToTest, {
          slotProps: {
            textField: {
              error: true
            }
          }
        }));
        const textBoxes = _utils.screen.getAllByRole('textbox');
        textBoxes.forEach(textbox => {
          (0, _chai.expect)(textbox.parentElement).to.have.class(_InputBase.inputBaseClasses.error);
          (0, _chai.expect)(textbox).to.have.attribute('aria-invalid', 'true');
        });
      });
    });
  });
};
exports.testControlledUnControlled = testControlledUnControlled;