efe31ae32e
* updates model validations to support warnings and adds alert to form field * adds changelog entry * updates model validations tests
137 lines
4.1 KiB
JavaScript
137 lines
4.1 KiB
JavaScript
/**
|
|
* Copyright (c) HashiCorp, Inc.
|
|
* SPDX-License-Identifier: MPL-2.0
|
|
*/
|
|
|
|
import { module, test } from 'qunit';
|
|
import { setupTest } from 'ember-qunit';
|
|
import { withModelValidations } from 'vault/decorators/model-validations';
|
|
import validators from 'vault/utils/validators';
|
|
import sinon from 'sinon';
|
|
import Model from '@ember-data/model';
|
|
|
|
// create class using decorator
|
|
const createClass = (validations) => {
|
|
@withModelValidations(validations)
|
|
class Foo extends Model {}
|
|
const foo = Foo.extend({
|
|
modelName: 'bar',
|
|
foo: null,
|
|
integer: null,
|
|
});
|
|
return new foo();
|
|
};
|
|
|
|
module('Unit | Decorators | ModelValidations', function (hooks) {
|
|
setupTest(hooks);
|
|
|
|
hooks.beforeEach(function () {
|
|
this.spy = sinon.spy(console, 'error');
|
|
});
|
|
hooks.afterEach(function () {
|
|
this.spy.restore();
|
|
});
|
|
|
|
test('it should throw error when validations object is not provided', function (assert) {
|
|
assert.expect(1);
|
|
|
|
try {
|
|
createClass();
|
|
} catch (e) {
|
|
assert.strictEqual(e.message, 'Validations object must be provided to constructor for setup');
|
|
}
|
|
});
|
|
|
|
test('it should log error to console when validations are not passed as array', function (assert) {
|
|
const validations = {
|
|
foo: { type: 'presence', message: 'Foo is required' },
|
|
};
|
|
const fooClass = createClass(validations);
|
|
fooClass.validate();
|
|
const message = 'Must provide validations as an array for property "foo" on bar model';
|
|
assert.ok(this.spy.calledWith(message));
|
|
});
|
|
|
|
test('it should log error for incorrect validator type', function (assert) {
|
|
const validations = {
|
|
foo: [{ type: 'bar', message: 'Foo is bar' }],
|
|
};
|
|
const fooClass = createClass(validations);
|
|
fooClass.validate();
|
|
const message = `Validator type: "bar" not found. Available validators: ${Object.keys(validators).join(
|
|
', '
|
|
)}`;
|
|
assert.ok(this.spy.calledWith(message));
|
|
});
|
|
|
|
test('it should validate', function (assert) {
|
|
const message = 'This field is required';
|
|
const validations = {
|
|
foo: [{ type: 'presence', message }],
|
|
};
|
|
const fooClass = createClass(validations);
|
|
const v1 = fooClass.validate();
|
|
assert.false(v1.isValid, 'isValid state is correct when errors exist');
|
|
assert.deepEqual(
|
|
v1.state,
|
|
{ foo: { isValid: false, errors: [message], warnings: [] } },
|
|
'Correct state returned when property is invalid'
|
|
);
|
|
|
|
fooClass.foo = true;
|
|
const v2 = fooClass.validate();
|
|
assert.true(v2.isValid, 'isValid state is correct when no errors exist');
|
|
assert.deepEqual(
|
|
v2.state,
|
|
{ foo: { isValid: true, errors: [], warnings: [] } },
|
|
'Correct state returned when property is valid'
|
|
);
|
|
});
|
|
|
|
test('invalid form message has correct error count', function (assert) {
|
|
const message = 'This field is required';
|
|
const messageII = 'This field must be a number';
|
|
const validations = {
|
|
foo: [{ type: 'presence', message }],
|
|
integer: [{ type: 'number', messageII }],
|
|
};
|
|
const fooClass = createClass(validations);
|
|
const v1 = fooClass.validate();
|
|
assert.strictEqual(
|
|
v1.invalidFormMessage,
|
|
'There are 2 errors with this form.',
|
|
'error message says form as 2 errors'
|
|
);
|
|
|
|
fooClass.integer = 9;
|
|
const v2 = fooClass.validate();
|
|
assert.strictEqual(
|
|
v2.invalidFormMessage,
|
|
'There is an error with this form.',
|
|
'error message says form has an error'
|
|
);
|
|
|
|
fooClass.foo = true;
|
|
const v3 = fooClass.validate();
|
|
assert.strictEqual(v3.invalidFormMessage, null, 'invalidFormMessage is null when form is valid');
|
|
});
|
|
|
|
test('it should validate warnings', function (assert) {
|
|
const message = 'Value contains whitespace.';
|
|
const validations = {
|
|
foo: [
|
|
{
|
|
type: 'containsWhiteSpace',
|
|
message,
|
|
level: 'warn',
|
|
},
|
|
],
|
|
};
|
|
const fooClass = createClass(validations);
|
|
fooClass.foo = 'foo bar';
|
|
const { state, isValid } = fooClass.validate();
|
|
assert.true(isValid, 'Model is considered valid when there are only warnings');
|
|
assert.strictEqual(state.foo.warnings.join(' '), message, 'Warnings are returned');
|
|
});
|
|
});
|