Skip to content
Open
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
24 changes: 24 additions & 0 deletions sprint-3-stretch-exercises/card-validator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export function isCardValid(cardNum) {
if (typeof cardNum !== "number") {
return false;
}
Comment on lines +1 to +4

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.

Because of the way JavaScript represents numbers, isCardValid(9999999999999997) would evaluate to true.

Could you use AI to find out why, and then update your code (both function implementation and tests) to use other data type to represent card number?

const has16Length = String(cardNum).length === 16;
const seenDigits = [];
const isFinalEven = cardNum % 2 === 0;
let total = 0;
for (const num of String(cardNum)) {
if (!seenDigits.includes(num)) {
seenDigits.push(num);
}
const regex = /^\d$/;
if (!regex.test(num)) {
return false;
}
Comment on lines +13 to +16

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.

Note: Since you are using regex, you could also just use regex to check if the whole card number (as a string) contain 16 digits (outside the loop) instead of checking each digit one by one.

total += Number(num);
}
if (has16Length && isFinalEven && total > 16 && seenDigits.length >= 2) {
return true;
} else {
return false;
}
}
59 changes: 59 additions & 0 deletions sprint-3-stretch-exercises/card-validator.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// - Number must be 16 digits, all of them must be numbers.
// - You must have at least two different digits represented (all of the digits cannot be the same).
// - The final digit must be even.
// - The sum of all the digits must be greater than 16.

import { isCardValid } from "./card-validator.js";

test("card number should have 16 digits", () => {
const cardNumber = 1234567890987654;
const result = isCardValid(cardNumber);
expect(result).toEqual(true);
});
Comment on lines +8 to +12

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.

In addition to checking if the function can correctly return true when the specified condition is met, this test should also check if the function can correctly return false when the specified condition is not met.

The same also applies to other tests in this script.


test("card number should have at least two different digits, all of them cannot be the same", () => {
const cardNumber = 1111111111111111;
const result = isCardValid(cardNumber);
expect(result).toEqual(false);
});

test("final card digit must be even", () => {
const cardNumber = 1111111111111118;
const result = isCardValid(cardNumber);
expect(result).toEqual(true);
});

test("sum of all the digits must be greater than 16", () => {
const cardNumber = 2222333344445554;
const result = isCardValid(cardNumber);
expect(result).toEqual(true);
});

test("cardNumber must contains only numbers", () => {
const cardNumber = "1233341234444444";
const result = isCardValid(cardNumber);
expect(result).toEqual(false);
});

test("cardNumber sum is less than 16, should return false", () => {
const cardNumber = 1111111111111110;
const result = isCardValid(cardNumber);
expect(result).toEqual(false);
});

test("cardNumber uses invalid characters,should return false", () => {
const cardNumber = "a92332119c011112";
const result = isCardValid(cardNumber);
expect(result).toEqual(false);
});
test("cardNumber uses only one type of number,should return false", () => {
const cardNumber = 4444444444444444;
const result = isCardValid(cardNumber);
expect(result).toEqual(false);
});

test("cardNumber has odo final number, should return false", () => {
const cardNumber = 6666666666666661;
const result = isCardValid(cardNumber);
expect(result).toEqual(false);
});
4 changes: 4 additions & 0 deletions sprint-3-stretch-exercises/find.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ console.log(find("code your future", "z"));
// Pay particular attention to the following:

// a) How the index variable updates during the call to find
//index updates from value of 0 to increment value of +1 every time it loop through while loop if it reach length of str and won't find what it looks for function return -1
// b) What is the if statement used to check
//the if statement checks if str index character is at the same position as char index position we're looking for
// c) Why is index++ being used?
//every time our function loops through while statement index position increment by 1
// d) What is the condition index < str.length used for?
//while index is smaller than length of str the loop would run, if it reaches same value function return -1 instead
31 changes: 30 additions & 1 deletion sprint-3-stretch-exercises/password-validator.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@
const passwords = [];
export function isValidPassword(password) {
Comment on lines +1 to 2

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.

For higher flexibility, we could design the function to accept passwords as an optional second parameter (with a default value).

return password.length >= 5;
let hasUpper = false;
let hasLower = false;
let hasNumbers = false;
let hasSpecialChars = false;
const minLength = password.length >= 5;
const upperLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const lowerLetters = "abcdefghijklmnopqrstuvwxyz";
const numbers = "0123456789";
const specialChars = "!#$%.*&";

for (const char of password) {
hasUpper = upperLetters.includes(char) ? true : hasUpper;

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.

Note:

  hasUpper = upperLetters.includes(char) ? true : hasUpper;

is equivalent to

 hasUpper = hasUpper && upperLetters.includes(char);

or

  if (upperLetters.includes(char)) hasUpper = true;

Alternatively, you could use regex to check if password contains an uppercase letter in one statement.

hasLower = lowerLetters.includes(char) ? true : hasLower;
hasNumbers = numbers.includes(char) ? true : hasNumbers;

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.

Note: The term digit refers to a number in the range 0-9. A number may contain any number of digits.

hasSpecialChars = specialChars.includes(char) ? true : hasSpecialChars;
}
if (
minLength &&
hasLower &&
hasUpper &&
hasNumbers &&
hasSpecialChars &&
!passwords.includes(password)
) {
passwords.push(password);

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.

Is "adding the password being checked to a global variable" an expected behavior of this function?

return true;
} else {
return false;
}
}
46 changes: 38 additions & 8 deletions sprint-3-stretch-exercises/password-validator.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,41 @@ You must breakdown this problem in order to solve it. Find one test case first a
*/
import { isValidPassword } from "./password-validator.js";
test("password has at least 5 characters", () => {
// Arrange
const password = "12345";
// Act
const result = isValidPassword(password);
// Assert
expect(result).toEqual(true);
}
);
// Arrange
const password = "Aa1!";
// Act
const result = isValidPassword(password);
// Assert
expect(result).toEqual(false);
});

test("password have at least one uppercase letter(A-Z)", () => {
const password = "hello123";
const result = isValidPassword(password);
expect(result).toEqual(false);
});

test("password have at least one lowercase letter(a-z)", () => {
const password = "A123AA";
const result = isValidPassword(password);
expect(result).toEqual(false);
});

test("password have at least one number(0-9)", () => {
const password = "RRRqqq";
const result = isValidPassword(password);
expect(result).toEqual(false);
});
Comment on lines +39 to +43

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.

The function can return false for multiple reasons.
To test a specific reason, choose an input that satisfies all other conditions except the one you're targeting. This way, if the function returns false, you can confidently attribute it to that specific condition.

For example, the function might return false for "RRRqqq" not only because it lacks a digit, but also because it lacks a special symbol. As a result, we can't be certain that the function correctly handles the case of passwords have at least one digit, since multiple conditions are being violated simultaneously.


test("password have at least one special character(!#$%.*&)", () => {
const password = "R3ass3";
const result = isValidPassword(password);
expect(result).toEqual(false);
});

test("rejects a previously used password", () => {
const password = "Hello123!";

expect(isValidPassword(password)).toEqual(true);
expect(isValidPassword(password)).toEqual(false);
});
Loading