Skip to content

Commit 6f846ab

Browse files
Merge pull request #2698 from johanrd/day_fix/template-require-form-method
Post-merge-review: Fix template-require-form-method: throw on bad config; default enabled
2 parents 719580e + eaeb791 commit 6f846ab

2 files changed

Lines changed: 63 additions & 6 deletions

File tree

lib/rules/template-require-form-method.js

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ const DEFAULT_CONFIG = {
77
};
88

99
function parseConfig(config) {
10-
if (config === false || config === undefined) {
10+
if (config === false) {
1111
return false;
1212
}
1313

14-
if (config === true) {
14+
if (config === true || config === undefined) {
1515
return DEFAULT_CONFIG;
1616
}
1717

@@ -26,7 +26,13 @@ function parseConfig(config) {
2626
}
2727
}
2828

29-
return false;
29+
throw new Error(
30+
'template-require-form-method: invalid configuration. Expected one of:\n' +
31+
' * boolean - `true` to enable / `false` to disable\n' +
32+
' * object -- An object with the following keys:\n' +
33+
` * \`allowedMethods\` -- An array of allowed form \`method\` attribute values of \`${VALID_FORM_METHODS}\`\n` +
34+
`Received: ${JSON.stringify(config)}`
35+
);
3036
}
3137

3238
function makeErrorMessage(methods) {
@@ -51,12 +57,16 @@ module.exports = {
5157
schema: [
5258
{
5359
oneOf: [
60+
{ type: 'boolean' },
5461
{
5562
type: 'object',
5663
properties: {
5764
allowedMethods: {
5865
type: 'array',
5966
items: {
67+
// Accept any string so case-insensitive values like "get"
68+
// still pass schema validation; parseConfig normalizes to
69+
// upper-case and throws on values not in VALID_FORM_METHODS.
6070
type: 'string',
6171
},
6272
},
@@ -78,9 +88,10 @@ module.exports = {
7888
},
7989

8090
create(context) {
81-
// If no options provided, use defaults
82-
let config = context.options[0];
83-
config = config ? parseConfig(config) : DEFAULT_CONFIG;
91+
// Default-enabled: parseConfig(undefined) returns DEFAULT_CONFIG.
92+
// Pass `false` to explicitly disable the rule.
93+
const rawOption = context.options[0];
94+
const config = parseConfig(rawOption);
8495

8596
if (config === false) {
8697
return {};

tests/lib/rules/template-require-form-method.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const validHbs = [
99
options: [{ allowedMethods: ['get'] }],
1010
code: '<form method="GET"></form>',
1111
},
12+
// No options → default-enabled with POST,GET,DIALOG.
1213
'<form method="POST"></form>',
1314
'<form method="post"></form>',
1415
'<form method="GET"></form>',
@@ -20,9 +21,24 @@ const validHbs = [
2021
'<div/>',
2122
'<div></div>',
2223
'<div method="randomType"></div>',
24+
// Explicit `true` behaves identically to no options.
25+
{ options: [true], code: '<form method="POST"></form>' },
26+
// Explicit `false` disables the rule.
27+
{ options: [false], code: '<form></form>' },
2328
];
2429

2530
const invalidHbs = [
31+
// Default-enabled: no options → rule active with POST,GET,DIALOG.
32+
{
33+
code: '<form></form>',
34+
output: '<form method="POST"></form>',
35+
errors: [{ message: DEFAULT_ERROR }],
36+
},
37+
{
38+
code: '<form method="NOT_A_VALID_METHOD"></form>',
39+
output: '<form method="POST"></form>',
40+
errors: [{ message: DEFAULT_ERROR }],
41+
},
2642
{
2743
options: [{ allowedMethods: ['get'] }],
2844
code: '<form method="POST"></form>',
@@ -40,26 +56,31 @@ const invalidHbs = [
4056
],
4157
},
4258
{
59+
options: [true],
4360
code: '<form></form>',
4461
output: '<form method="POST"></form>',
4562
errors: [{ message: DEFAULT_ERROR }],
4663
},
4764
{
65+
options: [true],
4866
code: '<form method=""></form>',
4967
output: '<form method="POST"></form>',
5068
errors: [{ message: DEFAULT_ERROR }],
5169
},
5270
{
71+
options: [true],
5372
code: '<form method=42></form>',
5473
output: '<form method="POST"></form>',
5574
errors: [{ message: DEFAULT_ERROR }],
5675
},
5776
{
77+
options: [true],
5878
code: '<form method=" ge t "></form>',
5979
output: '<form method="POST"></form>',
6080
errors: [{ message: DEFAULT_ERROR }],
6181
},
6282
{
83+
options: [true],
6384
code: '<form method=" pos t "></form>',
6485
output: '<form method="POST"></form>',
6586
errors: [{ message: DEFAULT_ERROR }],
@@ -100,3 +121,28 @@ hbsRuleTester.run('template-require-form-method', rule, {
100121
valid: validHbs,
101122
invalid: invalidHbs,
102123
});
124+
125+
// parseConfig should throw on an invalid `allowedMethods` entry so that
126+
// misconfiguration is surfaced immediately rather than silently ignored.
127+
describe('template-require-form-method invalid configuration', () => {
128+
const { Linter } = require('eslint');
129+
130+
function lintWith(options) {
131+
const linter = new Linter();
132+
linter.defineParser('ember-eslint-parser/hbs', require('ember-eslint-parser/hbs'));
133+
linter.defineRule('template-require-form-method', rule);
134+
return linter.verify('<form method="POST"></form>', {
135+
parser: 'ember-eslint-parser/hbs',
136+
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
137+
rules: { 'template-require-form-method': ['error', options] },
138+
});
139+
}
140+
141+
test('throws on unknown method in allowedMethods', () => {
142+
expect(() => lintWith({ allowedMethods: ['PATCH'] })).toThrow(/invalid configuration/);
143+
});
144+
145+
test('throws on mixed valid/invalid method list', () => {
146+
expect(() => lintWith({ allowedMethods: ['GET', 'BOGUS'] })).toThrow(/invalid configuration/);
147+
});
148+
});

0 commit comments

Comments
 (0)