Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions lib/rules/template-require-form-method.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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) {
Expand All @@ -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',
},
},
Expand All @@ -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 {};
Expand Down
46 changes: 46 additions & 0 deletions tests/lib/rules/template-require-form-method.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const validHbs = [
options: [{ allowedMethods: ['get'] }],
code: '<form method="GET"></form>',
},
// No options → default-enabled with POST,GET,DIALOG.
'<form method="POST"></form>',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why'd all these get removed? do we not want to test what happens with no options anymore?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, reverted, now, was only moved to wrappers on the sort { options: [true], code: ', but that was unnecessary for most.

'<form method="post"></form>',
'<form method="GET"></form>',
Expand All @@ -20,9 +21,24 @@ const validHbs = [
'<div/>',
'<div></div>',
'<div method="randomType"></div>',
// Explicit `true` behaves identically to no options.
{ options: [true], code: '<form method="POST"></form>' },
// Explicit `false` disables the rule.
{ options: [false], code: '<form></form>' },
];

const invalidHbs = [
// Default-enabled: no options → rule active with POST,GET,DIALOG.
{
code: '<form></form>',
output: '<form method="POST"></form>',
errors: [{ message: DEFAULT_ERROR }],
},
{
code: '<form method="NOT_A_VALID_METHOD"></form>',
output: '<form method="POST"></form>',
errors: [{ message: DEFAULT_ERROR }],
},
{
options: [{ allowedMethods: ['get'] }],
code: '<form method="POST"></form>',
Expand All @@ -40,26 +56,31 @@ const invalidHbs = [
],
},
{
options: [true],
code: '<form></form>',
output: '<form method="POST"></form>',
errors: [{ message: DEFAULT_ERROR }],
},
{
options: [true],
code: '<form method=""></form>',
output: '<form method="POST"></form>',
errors: [{ message: DEFAULT_ERROR }],
},
{
options: [true],
code: '<form method=42></form>',
output: '<form method="POST"></form>',
errors: [{ message: DEFAULT_ERROR }],
},
{
options: [true],
code: '<form method=" ge t "></form>',
output: '<form method="POST"></form>',
errors: [{ message: DEFAULT_ERROR }],
},
{
options: [true],
code: '<form method=" pos t "></form>',
output: '<form method="POST"></form>',
errors: [{ message: DEFAULT_ERROR }],
Expand Down Expand Up @@ -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('<form method="POST"></form>', {
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/);
});
});
Loading