Skip to content

Commit 5101d33

Browse files
committed
Fix template-require-form-method: throw on bad config; default disabled
parseConfig now throws on invalid allowedMethods (matches upstream's strictness instead of silently disabling). parseConfig(undefined) returns false so the rule doesn't run when options are omitted (matches upstream default). Schema accepts boolean root for parity.
1 parent a98bbca commit 5101d33

2 files changed

Lines changed: 66 additions & 15 deletions

File tree

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

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,16 @@ function parseConfig(config) {
2626
}
2727
}
2828

29-
return false;
29+
// Invalid configuration (e.g. unknown method in allowedMethods). Throw a
30+
// descriptive error to surface the problem to the user, matching upstream
31+
// ember-template-lint (which throws instead of silently disabling).
32+
throw new Error(
33+
'template-require-form-method: invalid configuration. Expected one of:\n' +
34+
' * boolean - `true` to enable / `false` to disable\n' +
35+
' * object -- An object with the following keys:\n' +
36+
` * \`allowedMethods\` -- An array of allowed form \`method\` attribute values of \`${VALID_FORM_METHODS}\`\n` +
37+
`Received: ${JSON.stringify(config)}`
38+
);
3039
}
3140

3241
function makeErrorMessage(methods) {
@@ -51,12 +60,16 @@ module.exports = {
5160
schema: [
5261
{
5362
oneOf: [
63+
{ type: 'boolean' },
5464
{
5565
type: 'object',
5666
properties: {
5767
allowedMethods: {
5868
type: 'array',
5969
items: {
70+
// Accept any string so case-insensitive values like "get"
71+
// still pass schema validation; parseConfig normalizes to
72+
// upper-case and throws on values not in VALID_FORM_METHODS.
6073
type: 'string',
6174
},
6275
},
@@ -78,9 +91,12 @@ module.exports = {
7891
},
7992

8093
create(context) {
81-
// If no options provided, use defaults
82-
let config = context.options[0];
83-
config = config ? parseConfig(config) : DEFAULT_CONFIG;
94+
// Match upstream ember-template-lint: when no options are provided,
95+
// parseConfig(undefined) returns false and the rule is disabled. This
96+
// rule must be enabled explicitly via `true` or an `allowedMethods`
97+
// object.
98+
const rawOption = context.options[0];
99+
const config = parseConfig(rawOption);
84100

85101
if (config === false) {
86102
return {};

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

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,22 @@ const validHbs = [
99
options: [{ allowedMethods: ['get'] }],
1010
code: '<form method="GET"></form>',
1111
},
12-
'<form method="POST"></form>',
13-
'<form method="post"></form>',
14-
'<form method="GET"></form>',
15-
'<form method="get"></form>',
16-
'<form method="DIALOG"></form>',
17-
'<form method="dialog"></form>',
18-
'<form method="{{formMethod}}"></form>',
19-
'<form method={{formMethod}}></form>',
20-
'<div/>',
21-
'<div></div>',
22-
'<div method="randomType"></div>',
12+
// Default behavior: when no options are provided, the rule is disabled
13+
// (matching upstream ember-template-lint). A bare <form> should NOT error.
14+
'<form></form>',
15+
'<form method="NOT_A_VALID_METHOD"></form>',
16+
{ options: [true], code: '<form method="POST"></form>' },
17+
{ options: [true], code: '<form method="post"></form>' },
18+
{ options: [true], code: '<form method="GET"></form>' },
19+
{ options: [true], code: '<form method="get"></form>' },
20+
{ options: [true], code: '<form method="DIALOG"></form>' },
21+
{ options: [true], code: '<form method="dialog"></form>' },
22+
{ options: [true], code: '<form method="{{formMethod}}"></form>' },
23+
{ options: [true], code: '<form method={{formMethod}}></form>' },
24+
{ options: [true], code: '<div/>' },
25+
{ options: [true], code: '<div></div>' },
26+
{ options: [true], code: '<div method="randomType"></div>' },
27+
{ options: [false], code: '<form></form>' },
2328
];
2429

2530
const invalidHbs = [
@@ -40,26 +45,31 @@ const invalidHbs = [
4045
],
4146
},
4247
{
48+
options: [true],
4349
code: '<form></form>',
4450
output: '<form method="POST"></form>',
4551
errors: [{ message: DEFAULT_ERROR }],
4652
},
4753
{
54+
options: [true],
4855
code: '<form method=""></form>',
4956
output: '<form method="POST"></form>',
5057
errors: [{ message: DEFAULT_ERROR }],
5158
},
5259
{
60+
options: [true],
5361
code: '<form method=42></form>',
5462
output: '<form method="POST"></form>',
5563
errors: [{ message: DEFAULT_ERROR }],
5664
},
5765
{
66+
options: [true],
5867
code: '<form method=" ge t "></form>',
5968
output: '<form method="POST"></form>',
6069
errors: [{ message: DEFAULT_ERROR }],
6170
},
6271
{
72+
options: [true],
6373
code: '<form method=" pos t "></form>',
6474
output: '<form method="POST"></form>',
6575
errors: [{ message: DEFAULT_ERROR }],
@@ -100,3 +110,28 @@ hbsRuleTester.run('template-require-form-method', rule, {
100110
valid: validHbs,
101111
invalid: invalidHbs,
102112
});
113+
114+
// Upstream-aligned error-surfacing tests. parseConfig should throw on an
115+
// invalid `allowedMethods` entry rather than silently disabling the rule.
116+
describe('template-require-form-method invalid configuration', () => {
117+
const { Linter } = require('eslint');
118+
119+
function lintWith(options) {
120+
const linter = new Linter();
121+
linter.defineParser('ember-eslint-parser/hbs', require('ember-eslint-parser/hbs'));
122+
linter.defineRule('template-require-form-method', rule);
123+
return linter.verify('<form method="POST"></form>', {
124+
parser: 'ember-eslint-parser/hbs',
125+
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
126+
rules: { 'template-require-form-method': ['error', options] },
127+
});
128+
}
129+
130+
test('throws on unknown method in allowedMethods', () => {
131+
expect(() => lintWith({ allowedMethods: ['PATCH'] })).toThrow(/invalid configuration/);
132+
});
133+
134+
test('throws on mixed valid/invalid method list', () => {
135+
expect(() => lintWith({ allowedMethods: ['GET', 'BOGUS'] })).toThrow(/invalid configuration/);
136+
});
137+
});

0 commit comments

Comments
 (0)