"use strict";

require("core-js/modules/es.symbol");

require("core-js/modules/es.array.filter");

require("core-js/modules/es.array.find");

require("core-js/modules/es.array.for-each");

require("core-js/modules/es.array.iterator");

require("core-js/modules/es.object.define-properties");

require("core-js/modules/es.object.define-property");

require("core-js/modules/es.object.get-own-property-descriptor");

require("core-js/modules/es.object.get-own-property-descriptors");

require("core-js/modules/es.object.keys");

require("core-js/modules/es.object.to-string");

require("core-js/modules/es.string.iterator");

require("core-js/modules/es.weak-map");

require("core-js/modules/web.dom-collections.for-each");

require("core-js/modules/web.dom-collections.iterator");

var _react = _interopRequireDefault(require("react"));

var _enzyme = require("enzyme");

var _2 = _interopRequireWildcard(require("."));

function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; if (obj != null) { var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (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; }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

var values = {
  a: true,
  b: null,
  c: ['1', '2'],
  d: {
    d1: 'nested'
  }
};

var noop = function noop() {};

var context = {
  ffOnChange: noop,
  ffUpdateValidation: noop,
  ffGetValue: function ffGetValue() {
    return values;
  },
  ffFullName: function ffFullName() {
    return [];
  },
  formSubscription: {
    subscribe: noop,
    unsubscribe: noop
  }
};
describe('components/runValidationRules', function () {
  test('should support a validation function', function () {
    var rule = jest.fn();
    (0, _2.runValidationRules)(rule, {}, noop);
    expect(rule).toHaveBeenCalledTimes(1);
    expect(rule).toHaveBeenLastCalledWith({}, noop);
  });
  test('should support an array of validation functions', function () {
    var rule1 = jest.fn();
    var rule2 = jest.fn();
    (0, _2.runValidationRules)([rule1, rule2], {}, noop);
    expect(rule1).toHaveBeenCalledTimes(1);
    expect(rule1).toHaveBeenLastCalledWith({}, noop);
    expect(rule2).toHaveBeenCalledTimes(1);
    expect(rule2).toHaveBeenLastCalledWith({}, noop);
  });
  test('should support an object of validation functions, nesting the value by key', function () {
    var rules = {
      a: jest.fn(),
      c: jest.fn(function (_, invalidate) {
        return invalidate('Test');
      })
    };
    var invalidateSpy = jest.fn(noop);
    (0, _2.runValidationRules)(rules, values, invalidateSpy);
    expect(rules.a).toHaveBeenCalledTimes(1);
    expect(rules.a.mock.calls[0][0]).toBe(values.a);
    expect(rules.c).toHaveBeenCalledTimes(1);
    expect(rules.c.mock.calls[0][0]).toBe(values.c);
    expect(invalidateSpy).toHaveBeenCalledTimes(1);
    expect(invalidateSpy).toHaveBeenLastCalledWith('Test', ['c']);
  });
  test('should support arrays and objects nested in objects', function () {
    var rules = {
      c: [jest.fn(function (_, invalidate) {
        return invalidate('Test');
      }), jest.fn()],
      d: {
        d1: jest.fn(function (_, invalidate) {
          return invalidate('Test');
        })
      }
    };
    var invalidateSpy = jest.fn(noop);
    (0, _2.runValidationRules)(rules, values, invalidateSpy);
    expect(rules.c[0]).toHaveBeenCalledTimes(1);
    expect(rules.c[0].mock.calls[0][0]).toBe(values.c);
    expect(invalidateSpy).toHaveBeenCalledWith('Test', ['c']);
    expect(rules.c[1]).toHaveBeenCalledTimes(1);
    expect(rules.c[1].mock.calls[0][0]).toBe(values.c);
    expect(rules.d.d1).toHaveBeenCalledTimes(1);
    expect(rules.d.d1.mock.calls[0][0]).toBe(values.d.d1);
    expect(invalidateSpy).toHaveBeenCalledWith('Test', ['d', 'd1']);
  });
});
describe('components/Validation', function () {
  test('should run validation when mounting', function () {
    var ffUpdateValidation = jest.fn();
    var rule = jest.fn(function (_, invalidate) {
      return invalidate('test');
    });
    (0, _enzyme.shallow)(_react["default"].createElement(_2["default"], {
      rules: rule
    }), {
      context: _objectSpread({}, context, {
        ffUpdateValidation: ffUpdateValidation
      })
    });
    expect(rule).toHaveBeenCalledTimes(1);
    expect(ffUpdateValidation).toHaveBeenCalledTimes(1);
    expect(ffUpdateValidation).toHaveBeenLastCalledWith([], [[[], 'test']]);
  });
  test('should run validation after an update has been triggered', function () {
    var triggerUpdate; // Only invalidate on the second call

    var rule = jest.fn(function (_, invalidate) {
      return rule.mock.calls.length === 2 ? invalidate('test') : false;
    });

    var componentContext = _objectSpread({}, context, {
      ffUpdateValidation: jest.fn(),
      formSubscription: {
        subscribe: function subscribe(func) {
          triggerUpdate = func;
        },
        unsubscribe: noop
      }
    });

    (0, _enzyme.shallow)(_react["default"].createElement(_2["default"], {
      rules: rule
    }), {
      context: componentContext
    });
    expect(rule).toHaveBeenCalledTimes(1);
    expect(componentContext.ffUpdateValidation).not.toHaveBeenCalled();
    triggerUpdate();
    expect(rule).toHaveBeenCalledTimes(2);
    expect(componentContext.ffUpdateValidation).toHaveBeenCalledTimes(1);
    expect(componentContext.ffUpdateValidation).toHaveBeenLastCalledWith([], [[[], 'test']]);
  });
  test('should only send updates if validation results change', function () {
    var triggerUpdate;
    var error = false; // Only invalidate on the second call

    var rule = jest.fn(function (_, invalidate) {
      return error ? invalidate(error) : false;
    });

    var componentContext = _objectSpread({}, context, {
      ffUpdateValidation: jest.fn(),
      formSubscription: {
        subscribe: function subscribe(func) {
          triggerUpdate = func;
        },
        unsubscribe: noop
      }
    }); // No errors on first render


    (0, _enzyme.shallow)(_react["default"].createElement(_2["default"], {
      rules: rule
    }), {
      context: componentContext
    });
    expect(rule).toHaveBeenCalledTimes(1);
    expect(componentContext.ffUpdateValidation).not.toHaveBeenCalled(); // No errors on second render

    triggerUpdate();
    expect(rule).toHaveBeenCalledTimes(2);
    expect(componentContext.ffUpdateValidation).not.toHaveBeenCalled(); // Errors on third render

    error = 'Error';
    triggerUpdate();
    expect(rule).toHaveBeenCalledTimes(3);
    expect(componentContext.ffUpdateValidation).toHaveBeenCalledTimes(1);
    expect(componentContext.ffUpdateValidation).toHaveBeenLastCalledWith([], [[[], 'Error']]);
  });
  test('should remove validation when unmounting', function () {
    var rule = jest.fn(function (_, invalidate) {
      return invalidate('test');
    });

    var componentContext = _objectSpread({}, context, {
      ffUpdateValidation: jest.fn()
    });

    var wrapper = (0, _enzyme.shallow)(_react["default"].createElement(_2["default"], {
      rules: rule
    }), {
      context: componentContext
    });
    expect(rule).toHaveBeenCalledTimes(1);
    expect(componentContext.ffUpdateValidation).toHaveBeenCalledTimes(1);
    expect(componentContext.ffUpdateValidation).toHaveBeenLastCalledWith([], [[[], 'test']]);
    wrapper.unmount();
    expect(rule).not.toHaveBeenCalledTimes(2);
    expect(componentContext.ffUpdateValidation).toHaveBeenCalledTimes(2);
    expect(componentContext.ffUpdateValidation).toHaveBeenLastCalledWith([[[], 'test']], []);
  });
  test('should render a list of errors', function () {
    var triggerUpdate;

    var componentContext = _objectSpread({}, context, {
      formSubscription: {
        subscribe: function subscribe(func) {
          triggerUpdate = func;
        },
        unsubscribe: noop
      }
    });

    var makeRule = function makeRule(error) {
      return function (_, invalidate) {
        return invalidate(error);
      };
    };

    var rules = makeRule('test');
    var wrapper = (0, _enzyme.mount)(_react["default"].createElement(_2["default"], {
      rules: rules
    }), {
      context: componentContext
    });
    expect(wrapper.find('li').length).toBe(1);
    rules = makeRule('change message');
    wrapper.setProps({
      rules: rules
    }); // TODO: Triggering the update and render here instead of from the
    // ffUpdateValidation context, and it needs to be cleaned up

    triggerUpdate();
    wrapper.update();
    expect(wrapper.find('li').length).toBe(1);
    expect(wrapper.find('li').text()).toBe('change message'); // Set the rules to two rules

    rules = [rules, makeRule('error')];
    wrapper.setProps({
      rules: rules
    }); // TODO: Triggering the update and render here instead of from the
    // ffUpdateValidation context, and it needs to be cleaned up

    triggerUpdate();
    wrapper.update();
    expect(wrapper.find('li').length).toBe(2);
  });
  test('should support displaying errors before or after children', function () {
    var rules = function rules(_, invalidate) {
      return invalidate('Error');
    };

    expect((0, _enzyme.shallow)(_react["default"].createElement(_2["default"], {
      rules: rules
    }, "Child"), {
      context: context
    }).text()).toBe('ChildError');
    expect((0, _enzyme.shallow)(_react["default"].createElement(_2["default"], {
      rules: rules,
      displayBeforeChildren: true
    }, "Child"), {
      context: context
    }).text()).toBe('ErrorChild');
  });
});