diff --git a/lib/form/validate.js b/lib/form/validate.js index 1c17954..722108d 100644 --- a/lib/form/validate.js +++ b/lib/form/validate.js @@ -200,12 +200,23 @@ const buildValues = working => { * * @param {object} input - Input Type being tested * @param {ValidationSettings} settings - All validation settings + * @param {function} validation - The validation function to run + * @param {string} required - The required check to run (save/publish) * * @returns {true|FormInputValues} - Returns `true` if there are no validation or required issues, {FormInputValues} with error messages as values if there are */ -const valueCheck = (input, settings, validation) => { - if (input.target.hasOwnProperty('required') && (input.target.required === 'save' || input.target.required === 'publish') && input.target.value === '') { - return 'Field cannot be left blank!'; +const valueCheck = (input, settings, validation, required) => { + // Check for Required + if (input.target.hasOwnProperty('required') && input.target.value === '') { + // Only require a publishable field if we're checking against publish + if (required === 'publish' && input.target.required === 'publish') { + return 'Field is required to be published!'; + } + + // Only return require save fields + if (input.target.required === 'save') { + return 'Field is required to be saved!'; + } } if (settings.repeatable.hasOwnProperty('min') && ((!Array.isArray(input.all) && settings.repeatable.min > 1) || (Array.isArray(input.all) && input.all.length < settings.repeatable.min))) { @@ -220,10 +231,21 @@ const valueCheck = (input, settings, validation) => { * * @param {FormInputValues} raw - Raw form input * @param {InputType} type - Individual input type + * @param {string} check - Either `save`, `publish` to validate required correctly * * @returns {true|FormInputValues} - Returns `true` if there are no validation issues, {FormInputValues} with error messages as values if there are */ -const validate = (raw, type) => { +const validate = (raw, type, check) => { + let required = check; + + if (typeof required === 'undefined') { + required = 'publish'; + } + + if (typeof required !== 'string' || ['save', 'publish'].indexOf(required) < 0) { + throw new Error('Parameter `check` must either be `save` or `publish`'); + } + let working = split(raw); const allSettings = buildSettings(type); const allRepeatables = buildRepeatables(type); @@ -257,7 +279,7 @@ const validate = (raw, type) => { } // Run the validation function - result.validation = valueCheck(input, settings, plugin.validation[plugin.inputs[0][result.input].validation.function]); + result.validation = valueCheck(input, settings, plugin.validation[plugin.inputs[0][result.input].validation.function], required); } // check if input is required, supersede main plugin @@ -267,7 +289,7 @@ const validate = (raw, type) => { } // Run the validation function - result.validation = valueCheck(input, settings, plugin.validation[plugin.inputs[result.input].validation.function]); + result.validation = valueCheck(input, settings, plugin.validation[plugin.inputs[result.input].validation.function], required); } return result; diff --git a/tests/fixtures/content-types/baz.yml b/tests/fixtures/content-types/baz.yml index b3fb4f7..d7c112f 100644 --- a/tests/fixtures/content-types/baz.yml +++ b/tests/fixtures/content-types/baz.yml @@ -11,7 +11,7 @@ attributes: inputs: text: settings: - empty: false + empty: true - type: text name: Input required save id: input-required-save @@ -20,7 +20,7 @@ attributes: text: required: 'save' settings: - empty: false + empty: true - type: text name: Plugin required publish id: plugin-required-publish @@ -29,7 +29,7 @@ attributes: inputs: text: settings: - empty: false + empty: true - type: text name: Input required publish id: input-required-publish @@ -38,7 +38,7 @@ attributes: text: required: 'publish' settings: - empty: false + empty: true - type: text name: Plugin required bad level id: plugin-required-bad-level @@ -47,7 +47,7 @@ attributes: inputs: text: settings: - empty: false + empty: true - type: text name: Input required bad level id: input-required-bad-level @@ -56,7 +56,7 @@ attributes: text: required: 'smublish' settings: - empty: false + empty: true - type: quote name: MULTI Plugin required save id: multi-plugin-required-save @@ -70,7 +70,7 @@ attributes: author: required: 'publish' settings: - empty: false + empty: true - type: selects-related name: Two related select elements id: input-related-selects diff --git a/tests/validate.js b/tests/validate.js index 4f75bd7..bbddd3e 100644 --- a/tests/validate.js +++ b/tests/validate.js @@ -259,7 +259,7 @@ test('Required - Pass', t => { }); }); -test('Required - Fail', t => { +test('Required Publish with Empty Save', t => { return types.only('baz').then(ct => { const input = { 'plugin-required-save--text': '', @@ -267,8 +267,8 @@ test('Required - Fail', t => { }; const expected = { - 'plugin-required-save--text': 'Field cannot be left blank!', - 'input-required-save--text': 'Field cannot be left blank!', + 'plugin-required-save--text': 'Field is required to be saved!', + 'input-required-save--text': 'Field is required to be saved!', }; const result = validation(input, ct); @@ -276,3 +276,50 @@ test('Required - Fail', t => { t.deepEqual(result, expected, 'Returns an object of inputs that have failed'); }); }); + +test('Required Publish with Empty Publish and Save', t => { + return types.only('baz').then(ct => { + const input = { + 'plugin-required-save--text': '', + 'input-required-publish--text': '', + }; + + const expected = { + 'plugin-required-save--text': 'Field is required to be saved!', + 'input-required-publish--text': 'Field is required to be published!', + }; + + const result = validation(input, ct); + + t.deepEqual(result, expected, 'Returns an object of inputs that have failed'); + }); +}); + + +test('Required Save with Empty Publish', t => { + return types.only('baz').then(ct => { + const input = { + 'plugin-required-publish--text': '', + 'input-required-publish--text': '', + }; + + const result = validation(input, ct, 'save'); + + t.true(result, 'No errors for just publish on save'); + }); +}); + +test('Validation fails if required check is wrong', t => { + return types.only('baz').then(ct => { + const input = { + 'plugin-required-publish--text': '', + 'input-required-publish--text': '', + }; + + validation(input, ct, 'foo'); + + t.fail(); + }).catch(e => { + t.is(e.message, 'Parameter `check` must either be `save` or `publish`', 'Errors out as expected'); + }); +});