diff --git a/lib/rules/template-require-form-method.js b/lib/rules/template-require-form-method.js index 66be830ca5..ae1f2eed46 100644 --- a/lib/rules/template-require-form-method.js +++ b/lib/rules/template-require-form-method.js @@ -7,11 +7,11 @@ const DEFAULT_CONFIG = { }; function parseConfig(config) { - if (config === false || config === undefined) { + if (config === false) { return false; } - if (config === true) { + if (config === true || config === undefined) { return DEFAULT_CONFIG; } @@ -26,7 +26,13 @@ function parseConfig(config) { } } - return false; + throw new Error( + 'template-require-form-method: invalid configuration. Expected one of:\n' + + ' * boolean - `true` to enable / `false` to disable\n' + + ' * object -- An object with the following keys:\n' + + ` * \`allowedMethods\` -- An array of allowed form \`method\` attribute values of \`${VALID_FORM_METHODS}\`\n` + + `Received: ${JSON.stringify(config)}` + ); } function makeErrorMessage(methods) { @@ -51,12 +57,16 @@ module.exports = { schema: [ { oneOf: [ + { type: 'boolean' }, { type: 'object', properties: { allowedMethods: { type: 'array', items: { + // Accept any string so case-insensitive values like "get" + // still pass schema validation; parseConfig normalizes to + // upper-case and throws on values not in VALID_FORM_METHODS. type: 'string', }, }, @@ -78,9 +88,10 @@ module.exports = { }, create(context) { - // If no options provided, use defaults - let config = context.options[0]; - config = config ? parseConfig(config) : DEFAULT_CONFIG; + // Default-enabled: parseConfig(undefined) returns DEFAULT_CONFIG. + // Pass `false` to explicitly disable the rule. + const rawOption = context.options[0]; + const config = parseConfig(rawOption); if (config === false) { return {}; diff --git a/tests/lib/rules/template-require-form-method.js b/tests/lib/rules/template-require-form-method.js index 5e3573b565..779519422a 100644 --- a/tests/lib/rules/template-require-form-method.js +++ b/tests/lib/rules/template-require-form-method.js @@ -9,6 +9,7 @@ const validHbs = [ options: [{ allowedMethods: ['get'] }], code: '
', }, + // No options → default-enabled with POST,GET,DIALOG. '
', '
', '
', @@ -20,9 +21,24 @@ const validHbs = [ '
', '
', '
', + // Explicit `true` behaves identically to no options. + { options: [true], code: '
' }, + // Explicit `false` disables the rule. + { options: [false], code: '
' }, ]; const invalidHbs = [ + // Default-enabled: no options → rule active with POST,GET,DIALOG. + { + code: '
', + output: '
', + errors: [{ message: DEFAULT_ERROR }], + }, + { + code: '
', + output: '
', + errors: [{ message: DEFAULT_ERROR }], + }, { options: [{ allowedMethods: ['get'] }], code: '
', @@ -40,26 +56,31 @@ const invalidHbs = [ ], }, { + options: [true], code: '
', output: '
', errors: [{ message: DEFAULT_ERROR }], }, { + options: [true], code: '
', output: '
', errors: [{ message: DEFAULT_ERROR }], }, { + options: [true], code: '
', output: '
', errors: [{ message: DEFAULT_ERROR }], }, { + options: [true], code: '
', output: '
', errors: [{ message: DEFAULT_ERROR }], }, { + options: [true], code: '
', output: '
', errors: [{ message: DEFAULT_ERROR }], @@ -100,3 +121,28 @@ hbsRuleTester.run('template-require-form-method', rule, { valid: validHbs, invalid: invalidHbs, }); + +// parseConfig should throw on an invalid `allowedMethods` entry so that +// misconfiguration is surfaced immediately rather than silently ignored. +describe('template-require-form-method invalid configuration', () => { + const { Linter } = require('eslint'); + + function lintWith(options) { + const linter = new Linter(); + linter.defineParser('ember-eslint-parser/hbs', require('ember-eslint-parser/hbs')); + linter.defineRule('template-require-form-method', rule); + return linter.verify('
', { + parser: 'ember-eslint-parser/hbs', + parserOptions: { ecmaVersion: 2022, sourceType: 'module' }, + rules: { 'template-require-form-method': ['error', options] }, + }); + } + + test('throws on unknown method in allowedMethods', () => { + expect(() => lintWith({ allowedMethods: ['PATCH'] })).toThrow(/invalid configuration/); + }); + + test('throws on mixed valid/invalid method list', () => { + expect(() => lintWith({ allowedMethods: ['GET', 'BOGUS'] })).toThrow(/invalid configuration/); + }); +});