@darkobits/formation
Version:
894 lines (717 loc) • 30.6 kB
JavaScript
;
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _unity = require('@darkobits/unity');
var _interfaces = require('../../etc/interfaces');
var _constants = require('../../etc/constants');
var _index = require('../../index');
var _index2 = _interopRequireDefault(_index);
var _FormationControl = require('../../classes/FormationControl');
var _Form = require('./Form');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
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; }
describe('FormController', function () {
var T = void 0;
var logSpy = jest.fn();
beforeEach(function () {
(0, _unity.module)(_index2.default, {
mock: {
$log: {
log: logSpy
}
}
});
T = (0, _unity.directive)('fm', {
template: '<fm></fm>'
});
});
// ----- Interfaces ----------------------------------------------------------
describe('[Interface] RegisterNgForm', function () {
it('should implement the RegisterNgForm interface', function () {
expect(_typeof(T.fm[_interfaces.RegisterNgForm])).toEqual('function');
});
it('should assign the ngForm controller to the correct key', function () {
expect(T.fm[_Form.NG_FORM_CONTROLLER]).toBeTruthy();
});
it('should expose validation properties from ngForm', function () {
var props = ['$dirty', '$invalid', '$pending', '$pristine', '$submitted', '$valid'];
props.forEach(function (prop) {
expect(Reflect.has(T.fm, prop)).toBe(true);
});
});
describe('trying to register multiple ngForms', function () {
it('should throw an error', function () {
var ngForm = (0, _unity.compile)({
template: '<form></form>',
scope: T.$scope.$new()
});
expect(function () {
T.fm[_interfaces.RegisterNgForm](ngForm);
}).toThrow(/ngForm already registered/);
});
});
});
describe('[Interface] RegisterForm', function () {
it('should implement the RegisterForm interface', function () {
expect(_typeof(T.fm[_interfaces.RegisterForm])).toEqual('function');
});
describe('when another child form with the same name is present', function () {
beforeEach(function () {
T = (0, _unity.directive)('fm', {
template: '\n <fm name="parentForm">\n <fm name="childForm"></fm>\n <transclude></transclude>\n </fm>\n '
});
});
it('should throw an error', function () {
var childForm = (0, _unity.compile)({
template: '<fm name="childForm"></fm>',
scope: T.$scope.$new()
});
var childFormCtrl = childForm.controller('fm');
expect(function () {
T.fm[_interfaces.RegisterForm](childFormCtrl);
}).toThrow('another child form with this name already exists');
});
});
describe('when a control with the same name is present', function () {
var name = 'foo';
beforeEach(function () {
T = (0, _unity.directive)('fm', {
template: '\n <fm name="parentForm">\n <fm-input name="' + name + '"></fm-input>\n <transclude></transclude>\n </fm>\n '
});
});
it('should throw an error', function () {
var childForm = (0, _unity.compile)({
template: '<fm name="' + name + '"></fm>',
scope: T.$scope.$new()
});
var childFormCtrl = childForm.controller('fm');
expect(function () {
T.fm[_interfaces.RegisterForm](childFormCtrl);
}).toThrow('a control with this name already exists');
});
});
describe('configuring the child form', function () {
var configKey = 'config';
var childFormName = 'childForm';
beforeEach(function () {
T = (0, _unity.directive)('fm', {
template: '\n <fm name="parentForm" controls="' + configKey + '">\n <transclude></transclude>\n </fm>\n ',
scope: _defineProperty({}, configKey, _defineProperty({}, childFormName, {
foo: 'bar'
}))
});
});
it('should pass configuration data to the child form', function () {
// Note: Add tests for this.
});
});
});
describe('[Interface] RegisterControl', function () {
it('should implement the RegisterControl interface', function () {
expect(_typeof(T.fm[_interfaces.RegisterControl])).toEqual('function');
});
describe('with a child form of the same name already registered', function () {
it('should throw an error', function () {
var controlName = 'foo';
expect(function () {
T = (0, _unity.directive)('fmInput', {
template: '<fm-input name="' + controlName + '"></fm-input>',
wrap: '\n <fm name="parentForm">\n <fm name="' + controlName + '"></fm>\n <transclude></transclude>\n </fm>\n '
});
}).toThrow('a child form with this name already exists');
});
});
});
describe('[Interface] RegisterNgModel', function () {
var controlName = 'foo';
var modelValue = 'bar';
beforeEach(function () {
T = (0, _unity.directive)('fm', {
template: '\n <fm>\n <input type="text" name="' + controlName + '" ng-model="vm.foo">\n </fm>\n ',
scope: {
vm: {
foo: modelValue
}
}
});
jest.spyOn(T.fm, _interfaces.RegisterNgModel);
(0, _unity.digest)();
});
it('should implement the RegisterNgModel interface', function () {
expect(_typeof(T.fm[_interfaces.RegisterNgModel])).toEqual('function');
});
it('should create a mock control', function () {
expect(T.fm.getControl(controlName)).toMatchObject({
name: controlName
});
expect(T.fm.getControl(controlName).getModelValue()).toEqual(modelValue);
});
});
describe('[Interface] Configure', function () {
var formName = 'form';
var configKey = 'config';
var controlNameA = 'foo';
var controlNameB = 'bar';
var errors = [['required', 'This field is required.']];
beforeEach(function () {
var _configKey2;
T = (0, _unity.directive)('fm', {
template: '\n <fm name="' + formName + '" controls="' + configKey + '">\n <fm-input name="' + controlNameA + '"></fm-input>\n <transclude></transclude>\n </fm>\n ',
scope: _defineProperty({}, configKey, (_configKey2 = {}, _defineProperty(_configKey2, controlNameA, {
errors: errors
}), _defineProperty(_configKey2, controlNameB, {
errors: errors
}), _configKey2))
});
});
it('should implement the Configure interface', function () {
expect(_typeof(T.fm[_interfaces.Configure])).toEqual('function');
});
it('should configure known entities', function () {
expect(T.fm.getControl(controlNameA).getErrorMessages()).toEqual(errors);
});
it('should cache configuration data and pass it to newly-registered controls', function () {
var controlB = (0, _unity.compile)({
template: '<fm-input name="' + controlNameB + '""></fm-input>',
insertAt: T.$element.find('transclude')
}).controller('fmInput');
expect(controlB.getErrorMessages()).toEqual(errors);
});
it('should throw an error if not passed an object', function () {
expect(function () {
T.fm[_interfaces.Configure]('foo');
}).toThrow('expected configuration to be of type Object or Undefined');
});
});
describe('[Interface] GetModelValue / SetModelValue', function () {
var spies = {};
var modelValues = {
foo: 'bar',
childForm: {
childFoo: 'bar'
},
group: [{
groupedFoo1: 'bar'
}, {
groupedFoo2: 'bar'
}]
};
beforeEach(function () {
T = (0, _unity.directive)('fm', {
template: '\n <fm>\n <fm-input name="foo"></fm-input>\n <fm name="childForm">\n <fm-input name="childFoo"></fm-input>\n </fm>\n <fm-group name="group">\n <fm name="grouped1">\n <fm-input name="groupedFoo1"></fm-input>\n </fm>\n <fm name="grouped2">\n <fm-input name="groupedFoo2"></fm-input>\n </fm>\n </fm-group>\n </fm>\n '
});
(0, _unity.digest)();
Object.assign(spies, {
foo: {
getModelValue: jest.spyOn(T.fm.getControl('foo'), _interfaces.GetModelValue),
setModelValue: jest.spyOn(T.fm.getControl('foo'), _interfaces.SetModelValue)
},
childForm: {
getModelValue: jest.spyOn(T.fm.getForm('childForm'), _interfaces.GetModelValue),
setModelValue: jest.spyOn(T.fm.getForm('childForm'), _interfaces.SetModelValue),
childFoo: {
getModelValue: jest.spyOn(T.fm.getForm('childForm').getControl('childFoo'), _interfaces.GetModelValue),
setModelValue: jest.spyOn(T.fm.getForm('childForm').getControl('childFoo'), _interfaces.SetModelValue)
}
},
group: {
getModelValue: jest.spyOn(T.fm.getForm('group'), _interfaces.GetModelValue),
setModelValue: jest.spyOn(T.fm.getForm('group'), _interfaces.SetModelValue),
grouped1: {
getModelValue: jest.spyOn(T.fm.getForm('group').getForm('grouped1'), _interfaces.GetModelValue),
setModelValue: jest.spyOn(T.fm.getForm('group').getForm('grouped1'), _interfaces.SetModelValue),
groupedFoo1: {
getModelValue: jest.spyOn(T.fm.getForm('group').getForm('grouped1').getControl('groupedFoo1'), _interfaces.GetModelValue),
setModelValue: jest.spyOn(T.fm.getForm('group').getForm('grouped1').getControl('groupedFoo1'), _interfaces.SetModelValue)
}
},
grouped2: {
getModelValue: jest.spyOn(T.fm.getForm('group').getForm('grouped2'), _interfaces.GetModelValue),
setModelValue: jest.spyOn(T.fm.getForm('group').getForm('grouped2'), _interfaces.SetModelValue),
groupedFoo2: {
getModelValue: jest.spyOn(T.fm.getForm('group').getForm('grouped2').getControl('groupedFoo2'), _interfaces.GetModelValue),
setModelValue: jest.spyOn(T.fm.getForm('group').getForm('grouped2').getControl('groupedFoo2'), _interfaces.SetModelValue)
}
}
}
});
});
it('should implement the SetModelValue interface', function () {
expect(_typeof(T.fm[_interfaces.SetModelValue])).toEqual('function');
});
it('should delegate to the SetModelValue interface of registry members', function () {
T.fm.setModelValues(modelValues);
(0, _unity.digest)();
expect(spies.foo.setModelValue.mock.calls.length).toEqual(1);
expect(spies.foo.setModelValue.mock.calls[0]).toEqual([modelValues.foo]);
expect(spies.childForm.setModelValue.mock.calls.length).toEqual(1);
expect(spies.childForm.setModelValue.mock.calls[0]).toEqual([modelValues.childForm]);
expect(spies.childForm.childFoo.setModelValue.mock.calls.length).toEqual(1);
expect(spies.childForm.childFoo.setModelValue.mock.calls[0]).toEqual([modelValues.childForm.childFoo]);
expect(spies.group.setModelValue.mock.calls.length).toEqual(1);
expect(spies.group.setModelValue.mock.calls[0]).toEqual([modelValues.group]);
expect(spies.group.grouped1.setModelValue.mock.calls.length).toEqual(1);
expect(spies.group.grouped1.setModelValue.mock.calls[0]).toEqual([modelValues.group[0]]);
expect(spies.group.grouped1.groupedFoo1.setModelValue.mock.calls.length).toEqual(1);
expect(spies.group.grouped1.groupedFoo1.setModelValue.mock.calls[0]).toEqual([modelValues.group[0].groupedFoo1]);
expect(spies.group.grouped2.setModelValue.mock.calls.length).toEqual(1);
expect(spies.group.grouped2.setModelValue.mock.calls[0]).toEqual([modelValues.group[1]]);
expect(spies.group.grouped2.groupedFoo2.setModelValue.mock.calls.length).toEqual(1);
expect(spies.group.grouped2.groupedFoo2.setModelValue.mock.calls[0]).toEqual([modelValues.group[1].groupedFoo2]);
});
it('should implement the GetModelValue interface', function () {
expect(_typeof(T.fm[_interfaces.GetModelValue])).toEqual('function');
});
it('should delegate to the GetModelValue interface of registry members', function () {
T.fm.setModelValues(modelValues);
(0, _unity.digest)();
var result = T.fm.getModelValues();
expect(result).toEqual(modelValues);
// Forms and form groups should have had GetModelValues invoked once.
expect(spies.childForm.getModelValue.mock.calls.length).toEqual(1);
expect(spies.group.getModelValue.mock.calls.length).toEqual(1);
expect(spies.group.grouped1.getModelValue.mock.calls.length).toEqual(1);
expect(spies.group.grouped2.getModelValue.mock.calls.length).toEqual(1);
// Child controls will have had GetModelValue invoked 3 times.
expect(spies.foo.getModelValue.mock.calls.length).toEqual(3);
expect(spies.childForm.childFoo.getModelValue.mock.calls.length).toEqual(3);
expect(spies.group.grouped1.groupedFoo1.getModelValue.mock.calls.length).toEqual(3);
expect(spies.group.grouped2.groupedFoo2.getModelValue.mock.calls.length).toEqual(3);
});
it('SetModelValue should throw an error if not passed an object', function () {
expect(function () {
T.fm[_interfaces.SetModelValue]('foo');
}).toThrow('expected model values to be of type Object or Undefined');
});
});
describe('[Interface] SetCustomErrorMessage', function () {
var controlName = 'foo';
var errorMessage = 'bar';
var errorData = _defineProperty({}, controlName, errorMessage);
beforeEach(function () {
T = (0, _unity.directive)('fm', {
template: '\n <fm>\n <fm-input name="' + controlName + '"></fm-input>\n </fm>\n '
});
});
it('should implement the SetCustomErrorMessage interface', function () {
expect(_typeof(T.fm[_interfaces.SetCustomErrorMessage])).toEqual('function');
});
it('should assign error messages to known controls', function () {
expect(T.fm.getControl(controlName)[_FormationControl.CUSTOM_ERROR_MESSAGE_KEY]).toBeFalsy();
T.fm[_interfaces.SetCustomErrorMessage](errorData);
expect(T.fm.getControl(controlName)[_FormationControl.CUSTOM_ERROR_MESSAGE_KEY]).toEqual(errorMessage);
});
it('should throw an error if not passed an object', function () {
expect(function () {
T.fm[_interfaces.SetCustomErrorMessage]('foo');
}).toThrow('expected error messages to be of type Object or Undefined');
});
});
describe('[Interface] ClearCustomErrorMessage', function () {
var controlName = 'foo';
var errorMessage = 'bar';
beforeEach(function () {
T = (0, _unity.directive)('fm', {
template: '\n <fm>\n <fm-input name="' + controlName + '"></fm-input>\n </fm>\n '
});
T.fm.getControl(controlName)[_interfaces.SetCustomErrorMessage](errorMessage);
});
it('should implement the ClearCustomErrorMessage interface', function () {
expect(_typeof(T.fm[_interfaces.ClearCustomErrorMessage])).toEqual('function');
});
it('should clear custom error messages from known controls', function () {
T.fm[_interfaces.ClearCustomErrorMessage]();
expect(T.fm.getControl(controlName)[_FormationControl.CUSTOM_ERROR_MESSAGE_KEY]).toBeFalsy();
});
});
describe('[Interface] Reset', function () {
var controlName = 'foo';
var resetSpy = void 0;
beforeEach(function () {
T = (0, _unity.directive)('fm', {
template: '\n <fm>\n <fm-input name="' + controlName + '"></fm-input>\n </fm>\n '
});
resetSpy = jest.spyOn(T.fm.getControl(controlName), _interfaces.Reset);
});
it('should implement the Reset interface', function () {
expect(_typeof(T.fm[_interfaces.Reset])).toEqual('function');
});
it('should set the $pristine flag to true', function () {
T.fm[_Form.NG_FORM_CONTROLLER].$setDirty();
expect(T.fm[_Form.NG_FORM_CONTROLLER].$pristine).toBeFalsy();
T.fm[_interfaces.Reset]();
expect(T.fm[_Form.NG_FORM_CONTROLLER].$pristine).toBeTruthy();
});
it('should delegate model values to known controls', function () {
var value = 'bar';
var modelValues = _defineProperty({}, controlName, value);
T.fm[_interfaces.Reset](modelValues);
(0, _unity.digest)();
expect(T.fm.getControl(controlName)[_interfaces.GetModelValue]()).toEqual(value);
expect(resetSpy.mock.calls[0]).toEqual([value]);
});
it('should throw an error if passed a truthy value that is not an object', function () {
expect(function () {
T.fm[_interfaces.Reset]();
}).not.toThrow();
expect(function () {
T.fm[_interfaces.Reset]('foo');
}).toThrow('expected model values to be of type Object or Undefined');
});
});
// ----- Semi-Private Methods ------------------------------------------------
describe('$debug', function () {
var message = 'foo';
beforeEach(function () {
T = (0, _unity.directive)('fm', {
template: '<fm debug></fm>'
});
});
it('should log debug messages when "$debugging" is true', function () {
T.fm.$debug(message);
expect(logSpy.mock.calls[0]).toEqual(expect.arrayContaining([message]));
});
});
describe('$onInit', function () {
describe('setting the "$debugging" flag', function () {
describe('when the "debug" attribute is present', function () {
beforeEach(function () {
T = (0, _unity.directive)('fm', {
template: '<fm debug></fm>'
});
});
it('should set the "$debugging" flag to "true"', function () {
expect(T.fm.$debugging).toBe(true);
});
});
describe('when the "debug" attribute is absent', function () {
beforeEach(function () {
T = (0, _unity.directive)('fm', {
template: '<fm></fm>'
});
});
it('should not set the "$debugging" flag to "true"', function () {
expect(T.fm.$debugging).toBeFalsy();
});
});
});
describe('assigning "$name" to parent scope', function () {
describe('when provided a non-empty string', function () {
var name = 'foo';
beforeEach(function () {
T = (0, _unity.directive)('fm', {
template: '<fm name="' + name + '"></fm>'
});
});
it('should assign the form controller to its parent scope', function () {
expect(T.$scope[name]).toBe(T.fm);
});
});
describe('when provided a falsy value', function () {
beforeEach(function () {
T = (0, _unity.directive)('fm', {
template: '<fm></fm>'
});
});
it('should assign an auto-generated name', function () {
expect(T.fm.name).toMatch(new RegExp('Form-\\d*'));
});
});
});
describe('parsing "$showErrorsOn"', function () {
describe('when provided a valid string', function () {
var attrString = 'touched, submitted';
var expectedFlags = ['$touched', '$submitted'];
beforeEach(function () {
T = (0, _unity.directive)('fm', {
template: '<fm show-errors-on="' + attrString + '"></fm>'
});
});
it('should parse the string into an array of flags', function () {
expect(T.fm.$getErrorBehavior()).toEqual(expectedFlags);
});
});
describe('when provided a falsy value', function () {
beforeEach(function () {
T = (0, _unity.directive)('fm', {
template: '<fm></fm>'
});
});
it('should no-op', function () {
expect(T.fm.$getErrorBehavior()).toBeFalsy();
});
});
describe('when provided an empty string', function () {
beforeEach(function () {
T = (0, _unity.directive)('fm', {
template: '<fm show-errors-on=""></fm>'
});
});
it('should no-op', function () {
expect(T.fm.$getErrorBehavior()).toBeFalsy();
});
});
});
});
describe('$unregisterControl', function () {
var controlName = 'foo';
beforeEach(function () {
T = (0, _unity.directive)('fm', {
template: '\n <fm>\n <fm-input name="' + controlName + '"></fm-input>\n </fm>\n '
});
});
it('should unregister the named control', function () {
var control = T.fm.getControl(controlName);
expect(T.fm.getControl(controlName)).toBeTruthy();
T.fm.$unregisterControl(control);
expect(T.fm.getControl(controlName)).toBeFalsy();
});
});
describe('$submit', function () {
jest.useFakeTimers();
var controlName = 'foo';
var onSubmitSpy = void 0;
var disableSpy = void 0;
var enableSpy = void 0;
var setValid = void 0;
var setPending = void 0;
var setSubmitting = void 0;
beforeEach(function () {
onSubmitSpy = jest.fn();
T = (0, _unity.directive)('fm', {
template: '\n <fm controls="controls" on-submit="onSubmit">\n <fm-input name="' + controlName + '"></fm-input>\n </fm>\n ',
scope: {
onSubmit: onSubmitSpy
}
});
(0, _unity.digest)();
// Spy on the form's enable / disable functions.
disableSpy = jest.spyOn(T.fm, 'disable');
enableSpy = jest.spyOn(T.fm, 'enable');
// Set up helpers to manipulate the ngForm controller's $valid and
// $pending states.
setValid = function setValid(value) {
T.fm[_Form.NG_FORM_CONTROLLER].$valid = Boolean(value);
T.fm[_Form.NG_FORM_CONTROLLER].$invalid = !value;
};
setPending = function setPending(value) {
T.fm[_Form.NG_FORM_CONTROLLER].$pending = Boolean(value);
};
// Set up a helper to manipulate the form's $submitting state.
setSubmitting = function setSubmitting(value) {
T.fm.$submitting = Boolean(value);
};
});
/**
* Scenario 1
*
* - [X] Form is already submitting
* - [ ] Form has pending async validators
* - [ ] Form is valid
* - [ ] Control has a custom error set
* - [ ] onSubmit returned field errors
*/
describe('Scenario 1', function () {
it('should return immediately', function () {
expect.assertions(1);
setSubmitting(true);
return T.fm.$submit().catch(function (err) {
expect(err.message).toEqual('SUBMIT_IN_PROGRESS');
});
});
});
/**
* Scenario 2
*
* - [ ] Form is already submitting
* - [X] Form has pending async validators
* - [ ] Form is valid
* - [ ] Control has a custom error set
* - [ ] onSubmit returned field errors
*/
describe('Scenario 2', function () {
it('should wait until $pending is "false"', function () {
expect.assertions(4);
setPending(true);
setValid(false);
// Queue up a micro-task that will execute as soon as we call
// runAllTimers().
setImmediate(function () {
return setPending(false);
});
var promise = T.fm.$submit().catch(function (err) {
expect(err.message).toEqual('NG_FORM_INVALID');
expect(disableSpy.mock.calls.length).toBe(1);
expect(onSubmitSpy.mock.calls.length).toBe(0);
expect(enableSpy.mock.calls.length).toBe(1);
});
jest.runAllTimers();
(0, _unity.digest)();
return promise;
});
});
/**
* Scenario 3
*
* - [ ] Form is already submitting
* - [X] Form has pending async validators
* - [X] Form is valid
* - [ ] Control has a custom error set
* - [ ] onSubmit returned field errors
*/
describe('Scenario 3', function () {
it('should wait until $pending is false, then call onSubmit', function () {
expect.assertions(3);
setPending(true);
setValid(true);
// Queue up a micro-task that will execute as soon as we call
// runAllTimers().
setImmediate(function () {
return setPending(false);
});
var promise = T.fm.$submit().then(function () {
expect(disableSpy.mock.calls.length).toBe(1);
expect(onSubmitSpy.mock.calls.length).toBe(1);
expect(enableSpy.mock.calls.length).toBe(1);
});
jest.runAllTimers();
(0, _unity.digest)();
return promise;
});
});
/**
* Scenario 4
*
* - [ ] Form is already submitting
* - [ ] Form has pending async validators
* - [X] Form is valid
* - [ ] Control has a custom error set
* - [X] onSubmit returned a promise
*/
describe('Scenario 4', function () {
it('should call onSubmit and apply field errors', function () {
expect.assertions(4);
var fieldError = 'bar';
var fieldErrors = _defineProperty({}, controlName, fieldError);
setPending(false);
setValid(true);
T.$scope.onSubmit = jest.fn(function () {
return fieldErrors;
});
var promise = T.fm.$submit().then(function () {
expect(disableSpy.mock.calls.length).toBe(1);
expect(T.$scope.onSubmit.mock.calls.length).toBe(1);
expect(enableSpy.mock.calls.length).toBe(1);
expect(T.fm.getControl(controlName)[_FormationControl.CUSTOM_ERROR_MESSAGE_KEY]).toBe(fieldError);
});
jest.runAllTimers();
(0, _unity.digest)();
return promise;
});
});
/**
* Scenario 5
*
* - [ ] Form is already submitting
* - [ ] Form has pending async validators
* - [X] Form is valid
* - [ ] Control has a custom error set
* - [ ] onSubmit returned field errors
*/
describe('Scenario 5', function () {
it('should indicate that onSubmit did not catch', function () {
expect.assertions(4);
var error = 'foo';
setPending(false);
setValid(true);
T.$scope.onSubmit = jest.fn(function () {
return Promise.reject(new Error(error));
});
var promise = T.fm.$submit().catch(function (err) {
expect(err.message).toBe(error);
expect(disableSpy.mock.calls.length).toBe(1);
expect(T.$scope.onSubmit.mock.calls.length).toBe(1);
expect(enableSpy.mock.calls.length).toBe(1);
});
jest.runAllTimers();
(0, _unity.digest)();
return promise;
});
});
/**
* Scenario 6
*
* - [ ] Form is already submitting
* - [ ] Form has pending async validators
* - [ ] Form is valid
* - [X] Control has a custom error set
* - [ ] onSubmit returned field errors
*/
describe('Scenario 6', function () {
it('should clear custom errors on controls', function () {
expect.assertions(6);
var customErrorMessage = 'foo';
T.fm.getControl(controlName)[_interfaces.SetCustomErrorMessage](customErrorMessage);
expect(T.fm.getControl(controlName)[_FormationControl.CUSTOM_ERROR_MESSAGE_KEY]).toBe(customErrorMessage);
setPending(false);
setValid(true);
var promise = T.fm.$submit().then(function () {
expect(T.fm.getControl(controlName)[_FormationControl.CUSTOM_ERROR_MESSAGE_KEY]).toBeFalsy();
expect(T.fm.getControl(controlName)[_constants.NG_MODEL_CTRL].$error[_constants.CUSTOM_ERROR_KEY]).toBeFalsy();
expect(disableSpy.mock.calls.length).toBe(1);
expect(onSubmitSpy.mock.calls.length).toBe(1);
expect(enableSpy.mock.calls.length).toBe(1);
});
jest.runAllTimers();
(0, _unity.digest)();
return promise;
});
});
});
// ----- Public Methods ------------------------------------------------------
describe('isDisabled', function () {
describe('when "$disabled" is truthy', function () {
beforeEach(function () {
T = (0, _unity.directive)('fm', {
template: '<fm></fm>'
});
T.fm.disable();
});
it('should return true', function () {
expect(T.fm.isDisabled()).toBe(true);
});
});
describe('when "$ngDisabled" is truthy', function () {
beforeEach(function () {
T = (0, _unity.directive)('fm', {
template: '<fm ng-disabled="true"></fm>'
});
});
it('should return true', function () {
expect(T.fm.isDisabled()).toBe(true);
});
});
describe('when neither "$disabled" nor "$ngDisabled" are truthy', function () {
beforeEach(function () {
T = (0, _unity.directive)('fm', {
template: '<fm></fm>'
});
});
it('should return falsy', function () {
expect(T.fm.isDisabled()).toBeFalsy();
});
});
});
describe('getControl', function () {
var ctrlName = 'foo';
var badName = 'bar';
beforeEach(function () {
T = (0, _unity.directive)('fm', {
template: '\n <fm>\n <fm-input name="' + ctrlName + '"></fm-input>\n </fm>\n '
});
});
it('should return the named control, if it exists', function () {
expect(T.fm.getControl(badName)).toBeFalsy();
expect(T.fm.getControl(ctrlName)).toBeTruthy();
});
});
});