-
-
Notifications
You must be signed in to change notification settings - Fork 218
NW | 25-ITP-Sep | TzeMing Ho | Sprint 3 | coursework/sprint-3-stretch #714
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
base: main
Are you sure you want to change the base?
NW | 25-ITP-Sep | TzeMing Ho | Sprint 3 | coursework/sprint-3-stretch #714
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.
This is looking really good - I left a few things to think about!
return false; | ||
} | ||
// check if the sanitized input contains only digits | ||
if (!/^\d{16}$/.test(sanitized)) { |
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.
By putting a {16}
here, you're checking the length again. This means we're checking the length twice.
This is fine, but if we wanted to change the expected length of a credit card, we'd need to change both.
Can you think how to avoid this duplication?
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.
Hi Daniel,
Thank you for pointing out that I have repeated the code. Regarding the issue, I have added a variable to store the value 16, and learned that if I want to apply the variable in a pattern, I need to call a new Regex function with the variable. It is something new and useful for me.
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 works! There are a couple of other ways I could imagine going about this - can you think what they may be? (Happy to just discuss them in this comment thread, you don't need to change the code any more :))
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.
I guess I understood what you meant by 'other ways.' Since we only have to check the length of 16 for once, the function will fail at the first condition check if the card number is not 16. I don't have to do it again in the second condition check. I could have focused on the characters that are all digits like /^\d+$/
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.
Exactly :) Alternatively you could keep the {16}
in the regex and delete the first length check completely (because any non-16-character string would fail the regex check).
describe("creditCardValidator", () => { | ||
test("should return true for a 16 digit long card number", () => { | ||
expect(creditCardValidator("1234-5678-9012-3456")).toBe(true); | ||
expect(creditCardValidator("1234 5678 9012 3456")).toBe(true); |
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.
Your tests all currently assume there are extra characters in the credit card number - is 123456789012345
valid? You may want to test that kind of thing too, to make sure your implementation doesn't assume there are separators.
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.
You are right. I should have included tests for card numbers that are more or fewer than 16 digits. As you suggested, I created one test for the case of fewer and another for more.
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.
These extra tests look good, but aren't quite getting at the problem I was pointing at - can you add a test for a 16-digit credit card number which is only numbers (i.e. no spaces or -
s)?
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.
Yeah. I included a test for only 16 digits without spaces or operators.
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 is looking great! I have yet more things to discuss, though, but hopefully they're all interesting!
const sum = sanitized | ||
.split("") | ||
.reduce((total, digit) => total + Number(digit), 0); | ||
if (sum <= VALID_LENGTH) { |
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.
It's not clear to me that the 16 here is related to the length of the number.
We want to be careful only to extract/share code where the reason for the sharing is the same. The first two places you use VALID_LENGTH
are definitely both about the length, but here I would either put 16 back in, or make a separate constant MINIMUM_SUM
or similar. Even though it happens to have the same value, if the reason is different, we don't want to share them. Otherwise e.g. if we changed the minimum sum, we may accidentally also change the expected length!
return false; | ||
} | ||
// check if the sanitized input contains only digits | ||
if (!/^\d{16}$/.test(sanitized)) { |
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 works! There are a couple of other ways I could imagine going about this - can you think what they may be? (Happy to just discuss them in this comment thread, you don't need to change the code any more :))
describe("creditCardValidator", () => { | ||
test("should return true for a 16 digit long card number", () => { | ||
expect(creditCardValidator("1234-5678-9012-3456")).toBe(true); | ||
expect(creditCardValidator("1234 5678 9012 3456")).toBe(true); |
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.
These extra tests look good, but aren't quite getting at the problem I was pointing at - can you add a test for a 16-digit credit card number which is only numbers (i.e. no spaces or -
s)?
const symbolCondition = /[!#$%.*&]/.test(password); | ||
console.log(`symbol condition: ${symbolCondition}`); | ||
|
||
const previousPasswords = [ |
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 feels like it should probably be input to the function, rather than something we hard-code in the function itself?
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.
Agree. I felt that it was something wrong to put a list of previous passwords inside a function. It should have been an input, which can be an array from a database or something very long and editable.
…iable name, and refactored previous password as a function input
Learners, PR Template
Self checklist
Changelist
In the stretch exercise, I have answered questions in find.js, created tests and a function for password validation, and created tests and a function for credit card.