-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added new rule to detect assertions where statusCode is in the parameter #97
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just a few things, also does it make sense to check number literal values such as 200/409/etc. because they are also frequently used in status code assertion? ideally they should be replaced by StatusCodes.OK/etc. from http-status-codes
package.
maybe it should be a separated rules? i'm not sure ...
src/no-status-code-assert.ts
Outdated
|
||
export const ruleId = 'no-status-code-assert'; | ||
const NO_STATUS_CODE_ASSERT = 'NO_STATUS_CODE_ASSERT'; | ||
const keywords = ['status', 'code', 'StatusCodes', 'statusCode']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
status
/code
are widely used in none response status code related assertions, e.g. things like account.status
/message.code
can be incorrectly labelled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@le-cong refactored to just check for StatusCodes for all assertions in parameters else if it is BinaryExpression check on either side.
src/no-status-code-assert.ts
Outdated
*/ | ||
const hasStatusCodeOrValue = (arg: TSESTree.Node): boolean => { | ||
const checkName = (name?: string): boolean => | ||
name !== undefined && keywords.some((keyword) => name.toLowerCase().includes(keyword)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the usage of name.toLowerCase()
seems contradict with the keyword const values which contains upper case values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just a few minor items
src/no-status-code-assert.ts
Outdated
node.object.name === 'assert' && | ||
node.property.type === AST_NODE_TYPES.Identifier; | ||
|
||
//Checks if a given AST node is an identifier with the name 'assert'. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove?
src/no-status-code-assert.ts
Outdated
|
||
const isAssertCallWithStatusCode = (callee: TSESTree.Node, args: TSESTree.Node[]): boolean => | ||
(isAssertIdentifier(callee) || isAssertMemberExpression(callee)) && | ||
args.some((arg) => hasStatusCodeOrValue(arg) && arg.type !== AST_NODE_TYPES.Identifier); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the arg.type check seems unnecessary given the fact that hasStatusCodeOrValue
function is already testing some specific conditions in its switch statements.
src/no-status-code-assert.ts
Outdated
switch (arg.type) { | ||
case AST_NODE_TYPES.Literal: | ||
if (typeof arg.value === 'number') { | ||
return isStatusCodeLiteral(arg.value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this branch doesn't have test coverage, either add test case or remove this logic and leave it for a separated rule to detect the direct usage of numeric value instead of http-status-codes for response status code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh we are just focusing on statusCodes, we can remove this
docs/rules/no-status-code-assert.md
Outdated
## Fail | ||
|
||
```js | ||
assert(statusCode === 200); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
update to reflect the latest implementation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@carlansley should we have rule to auto fix the prod code with statusCode if we have numbers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I can answer that, can we add a little more description to the issue/PR about what this entire rule is needed for? I'm sure this was discussed at some point but tbh I don't recall what the original problem was.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to monitor for assertion failures in production and also improve how assertions are used in production code. Currently, assertions are being used for status checks, which isn’t ideal. A good first step is to implement an ESLint rule that will detect when assertions are made using a statusCode as one of the parameters. This will help identify and clean up improper use of assertions in the code. notify service could look for assertion errors, but we need to clean up usage of assertions for status checks.
As we are checking for statusCode, should we have another rule to auto fix the prod code with statusCode if we have numbers some thing like
assert(statusCode === 200);
would be assert(statusCode === StatusCodes.OK);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a mistake in the documentation wrt what is "pass" and what is "fail"? That was what confused me initially.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But initially it was like
Fail
assert(statusCode === 200);
assert.equal(statusCode, 200);
Pass
assert(response.status === 200);
assert.equal(response.status, 200);
Updated the rule to handle just statusCodes.
Fail
assert(statusCode === StatusCodes.OK);
assert.equal(statusCode, StatusCodes.OK);
Pass
assert(response.status === 200);
assert.equal(response.status, 200);
Pass wouldn't report as StatusCodes aren't used. This was the reason if we need to have another rule to auto fix all the numbers to statusCodes?
docs/rules/no-status-code-assert.md
Outdated
assert(response.status === 200); | ||
assert.equal(response.status, 200); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't these be failures as well? In a nutshell, we want to disallow the usage of assert to check for the desired response status, whether by using status or statusCode, in production code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
status/code are widely used in none response status code related assertions, e.g. things like account.status/message.code can be incorrectly labelled. Should we check .status, .code in the params of assert instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure I understand, but all I'm saying is, just like how you're disallowing assert.ok(response.statusCode === StatusCodes.OK)
, we should also disallow assert.ok(response.status === StatusCodes.OK)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert.ok(response.status === StatusCodes.OK)
is disallowed and would be reported as error but assert.equal(response.status, 200);
is allowed since the rule check is going by StatusCodes. We can add that to disallow
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
created #109 to address the usage of magic number instead of StatusCodes.xxx
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@le-cong, why do we need a separate rule? if 200/201/400/500 etc., are used, it will fail with a no-magic-numbers
correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point, the only thing is that no-magic-number rule is turned off for test codes, thought we might want to be consistent with status code handling all across targeting a specific subset of numbers. thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no-magic-number
is turned off for https://github.com/checkdigit/eslint-config/blob/main/index.mjs#L208. So, the only HTTP response status codes that will be allowed would be 256 and 512, which are uncommon and I can't think of any services that use these.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
L208 is for default setting including production code, but it's overridden by the next section in https://github.com/checkdigit/eslint-config/blob/5eea1c576703f1ba1663bd6bb73542d19ccbce5d/index.mjs#L438, which disables this rule completely for test codes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
got it. the new GitHub issue you created makes sense to me then
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lftm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lftm, but main needs to be merged in
❌ PR review status - not all reviewers have approved - 2 approved - 1 outstanding |
Beta Published - Install Command: |
Closes #96
Tested with internal services