From 08c83d6e4ca42cf41d03ae570ad990ef59a397e9 Mon Sep 17 00:00:00 2001 From: Martin Mwaka Date: Sat, 4 Jul 2026 16:09:20 +0100 Subject: [PATCH 1/7] create card-validator.js file --- Sprint-3/4-stretch/card-validator.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Sprint-3/4-stretch/card-validator.js diff --git a/Sprint-3/4-stretch/card-validator.js b/Sprint-3/4-stretch/card-validator.js new file mode 100644 index 0000000000..e69de29bb2 From a043ba8785c1ede90c4bcc16cccaa568d6c8b750 Mon Sep 17 00:00:00 2001 From: Martin Mwaka Date: Sat, 4 Jul 2026 21:46:48 +0100 Subject: [PATCH 2/7] Complete 4-stretch/card-validator.js --- Sprint-3/4-stretch/card-validator.js | 71 ++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/Sprint-3/4-stretch/card-validator.js b/Sprint-3/4-stretch/card-validator.js index e69de29bb2..d9368d4773 100644 --- a/Sprint-3/4-stretch/card-validator.js +++ b/Sprint-3/4-stretch/card-validator.js @@ -0,0 +1,71 @@ +/* +Here are the rules for a valid number: + +- 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. + +For example, the following credit card numbers are valid: + +```markdown +9999777788880000 +6666666666661666 +``` + +And the following credit card numbers are invalid: + +```markdown +a92332119c011112 (invalid characters) +4444444444444444 (only one type of number) +1111111111111110 (sum less than 16) +6666666666666661 (odd final number) +``` + +These are the requirements your project needs to fulfill: + +- Make a JavaScript file with a name that describes its contents. +- Create a function with a descriptive name which makes it clear what the function does. The function should take one argument, the credit card number to validate. +- Write at least 2 comments that explain to others what a line of code is meant to do. +- Return a boolean from the function to indicate whether the credit card number is valid. + +Good luck! +*/ + +const validateCard = (card) => { + const cardStr = String(card); + // Must have 16 digits + const has16Digits = cardStr.length === 16; + // Must be all digits + const isAllDigits = /^\d+$/.test(cardStr); + // Must have at least 2 numbers + const hasMoreThanOneDigit = cardStr.length > 1; + // Final digit must be even + const hasEvenFinalDigit = isAllDigits && (Number(cardStr) % 10) % 2 === 0; + // Sum of numbers must be at least 16 + const sumOfNumbers = isAllDigits + ? cardStr.split("").reduce((acc, num) => acc + Number(num), 0) + : 0; + + const hasSumOver15 = sumOfNumbers > 15; + + // Must have more than one type of number + const hasMultipleDistinctDigits = new Set(cardStr.split("")).size > 1; + + return has16Digits && + hasMoreThanOneDigit && + hasEvenFinalDigit && + hasSumOver15 && + hasMultipleDistinctDigits + ? "Valid card" + : "Invalid card"; +}; + +console.log(validateCard(9999777788880000)); // valid +console.log(validateCard(6666666666661666)); // valid +console.log(validateCard("a92332119c011112")); // Invalid +console.log(validateCard(4444444444444444)); // Invalid +console.log(validateCard(1111111111111110)); // Invalid +console.log(validateCard(6666666666666661)); // Invalid + +module.exports = validateCard; From 5bc7e2bc586e67e5dcb310f822dd36932ee7d7c3 Mon Sep 17 00:00:00 2001 From: Martin Mwaka Date: Sat, 4 Jul 2026 22:16:11 +0100 Subject: [PATCH 3/7] Add tests to 4-stretch/card-validator.test.js --- Sprint-3/4-stretch/card-validator.test.js | 43 +++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 Sprint-3/4-stretch/card-validator.test.js diff --git a/Sprint-3/4-stretch/card-validator.test.js b/Sprint-3/4-stretch/card-validator.test.js new file mode 100644 index 0000000000..61f725ae4b --- /dev/null +++ b/Sprint-3/4-stretch/card-validator.test.js @@ -0,0 +1,43 @@ +const validateCard = require("./card-validator"); + +test("should have 16 digits, all numbers", () => { + const cardNumber = 9999777788880000; + const result = validateCard(cardNumber); + expect(result).toBe("Valid card"); +}); + +test("should not have less than 16 digits", () => { + const cardNumber = 99997777; + const result = validateCard(cardNumber); + expect(result).toBe("Invalid card"); +}); + +test("should have at least two different distinct digits", () => { + const cardNumber = 9999777788880000; + const result = validateCard(cardNumber); + expect(result).toBe("Valid card"); +}); + +test("should have even final digit", () => { + const cardNumber = 6666666666661666; + const result = validateCard(cardNumber); + expect(result).toBe("Valid card"); +}); + +test("total sum of numbers should be greater than 15", () => { + const cardNumber = 6666666666661666; + const result = validateCard(cardNumber); + expect(result).toBe("Valid card"); +}); + +test("single repeating digit is invalid", () => { + const cardNumber = 4444444444444444; + const result = validateCard(cardNumber); + expect(result).toBe("Invalid card"); +}); + +test("digits cannot include non numerals", () => { + const cardNumber = "a92332119c011112"; + const result = validateCard(cardNumber); + expect(result).toBe("Invalid card"); +}); From 7cd1603dd8d8d34d890329367eea23e3aa73f1af Mon Sep 17 00:00:00 2001 From: Martin Mwaka Date: Sun, 5 Jul 2026 07:37:28 +0100 Subject: [PATCH 4/7] Complete 4-stretch/find.js --- Sprint-3/4-stretch/find.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Sprint-3/4-stretch/find.js b/Sprint-3/4-stretch/find.js index c7e79a2f21..e151d130a4 100644 --- a/Sprint-3/4-stretch/find.js +++ b/Sprint-3/4-stretch/find.js @@ -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 +// [MM] - The index variable increments by one each time the letter (str[index]) at the current index does not match the target letter (char) // b) What is the if statement used to check +// [MM] - The if statement is used to check if the current letter matches the target letter (char). If a match is found (str[index] === char) it will cause an early exit from the while loop at the current index // c) Why is index++ being used? +// [MM] - The index++ increments the index variable by one each time the current letter (str[index]) does not match the target letter (char). It only runs if a match is not found // d) What is the condition index < str.length used for? +// [MM] - The condition index < str.length is used to set the upper bound of the loop (the loop will run while index number is less than str.length) From 012c657a53b56f380fae77522893b20765b89ac0 Mon Sep 17 00:00:00 2001 From: Martin Mwaka Date: Sun, 5 Jul 2026 08:39:03 +0100 Subject: [PATCH 5/7] Write tests for 4-stretch/password-validator.test.js --- Sprint-3/4-stretch/password-validator.test.js | 43 +++++++++++++++---- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/Sprint-3/4-stretch/password-validator.test.js b/Sprint-3/4-stretch/password-validator.test.js index 8fa3089d6b..5d49eca93d 100644 --- a/Sprint-3/4-stretch/password-validator.test.js +++ b/Sprint-3/4-stretch/password-validator.test.js @@ -16,11 +16,38 @@ You must breakdown this problem in order to solve it. Find one test case first a */ const isValidPassword = require("./password-validator"); test("password has at least 5 characters", () => { - // Arrange - const password = "12345"; - // Act - const result = isValidPassword(password); - // Assert - expect(result).toEqual(true); -} -); \ No newline at end of file + // Arrange + const password = "12345"; + // Act + const result = isValidPassword(password); + // Assert + expect(result).toEqual(true); +}); + +test("returns true for a valid password", () => { + expect(isValidPassword("Pen5!")).toBe(true); +}); + +test("returns false for a short password", () => { + expect(isValidPassword("Pen!")).toBe(false); +}); + +test("returns false if there is no uppercase English letter", () => { + expect(isValidPassword("pen5!")).toBe(false); +}); + +test("returns false if there is no lowercase English letter", () => { + expect(isValidPassword("PEN5!")).toBe(false); +}); + +test("returns false if there is no number", () => { + expect(isValidPassword("PENf!")).toBe(false); +}); + +test("returns false if there is no symbol", () => { + expect(isValidPassword("Pen5a")).toBe(false); +}); + +test("returns false if password is a previous password", () => { + expect(isValidPassword("HeLlo5.")).toBe(false); +}); From 3e569fa5cd7629eab529fdfbe2cc28ac57f3d117 Mon Sep 17 00:00:00 2001 From: Martin Mwaka Date: Sun, 5 Jul 2026 08:40:59 +0100 Subject: [PATCH 6/7] Complete password-validator.js --- Sprint-3/4-stretch/password-validator.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/Sprint-3/4-stretch/password-validator.js b/Sprint-3/4-stretch/password-validator.js index b55d527dba..776cfdf878 100644 --- a/Sprint-3/4-stretch/password-validator.js +++ b/Sprint-3/4-stretch/password-validator.js @@ -1,6 +1,16 @@ function passwordValidator(password) { - return password.length < 5 ? false : true -} + const previousPasswords = ["heLlo5.", "Su1ma#"]; + + const checks = { + minLength: password.length > 4, + hasUpperCase: /[A-Z]/.test(password), + hasLowerCase: /[a-z]/.test(password), + hasNumber: /[0-9]/.test(password), + hasSymbol: /[!#$%.*&]/.test(password), + notPreviousPassword: !previousPasswords.includes(password), + }; + return Object.values(checks).every(Boolean); +} -module.exports = passwordValidator; \ No newline at end of file +module.exports = passwordValidator; From 48629e08200a43be18b9852b1cf68f57d56d97ec Mon Sep 17 00:00:00 2001 From: Martin Mwaka Date: Sun, 5 Jul 2026 08:46:27 +0100 Subject: [PATCH 7/7] Update 4-stretch/password-validator.test.js - all tests pass --- Sprint-3/4-stretch/password-validator.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sprint-3/4-stretch/password-validator.test.js b/Sprint-3/4-stretch/password-validator.test.js index 5d49eca93d..59238a78d7 100644 --- a/Sprint-3/4-stretch/password-validator.test.js +++ b/Sprint-3/4-stretch/password-validator.test.js @@ -17,7 +17,7 @@ You must breakdown this problem in order to solve it. Find one test case first a const isValidPassword = require("./password-validator"); test("password has at least 5 characters", () => { // Arrange - const password = "12345"; + const password = "Pen5!"; // Act const result = isValidPassword(password); // Assert @@ -49,5 +49,5 @@ test("returns false if there is no symbol", () => { }); test("returns false if password is a previous password", () => { - expect(isValidPassword("HeLlo5.")).toBe(false); + expect(isValidPassword("heLlo5.")).toBe(false); });