From 4fa3ff315d29376c3183d4b5fa9b3e1c2c85ca5e Mon Sep 17 00:00:00 2001 From: Tomislav Dukez Date: Fri, 3 Jul 2026 16:20:14 +0100 Subject: [PATCH 1/8] add explanatory comments to task find.js --- Sprint-3/4-stretch/find.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Sprint-3/4-stretch/find.js b/Sprint-3/4-stretch/find.js index c7e79a2f21..49884e3db3 100644 --- a/Sprint-3/4-stretch/find.js +++ b/Sprint-3/4-stretch/find.js @@ -20,6 +20,19 @@ console.log(find("code your future", "z")); // Pay particular attention to the following: // a) How the index variable updates during the call to find +// The index variable starts at 0 and increments by 1 in each iteration of the while loop. +// In case of the call find("code your future", "u"), the index variable updates as follows: +// 0, 1, 2, 3, 4, 5, 6, 7 - when it stops, because the character at index 7 is "u" +// In case of the call find("code your future", "z"), the index variable updates as follows: +// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 - when it stops, because the condition index < str.length is no longer true +// the and because the loop has arrived to the end of the string without finding "z". + // b) What is the if statement used to check +// The if statement is used to check if the character at the current index is equal to the character we are looking for. + // c) Why is index++ being used? +// index++ is incrementing the index by 1 in each iteration of the while loop. this is how the index is being moved from 0 to the end of the string, or the index where the character is found. + // d) What is the condition index < str.length used for? +// It gives the limit to the looping, that is, the index must be less than the length of the string, and in case the index is equal or greater than the string length, the loop will stop. +// If this condition wasn't given, the loop would continue to run indefinitely. From 66c5040f277a78889f7fbe1a544003e75d5894be Mon Sep 17 00:00:00 2001 From: Tomislav Dukez Date: Fri, 3 Jul 2026 18:12:29 +0100 Subject: [PATCH 2/8] add check for pass length --- Sprint-3/4-stretch/password-validator.js | 8 ++++--- Sprint-3/4-stretch/password-validator.test.js | 24 ++++++++++++------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/Sprint-3/4-stretch/password-validator.js b/Sprint-3/4-stretch/password-validator.js index b55d527dba..062b943209 100644 --- a/Sprint-3/4-stretch/password-validator.js +++ b/Sprint-3/4-stretch/password-validator.js @@ -1,6 +1,8 @@ function passwordValidator(password) { - return password.length < 5 ? false : true + if (password.length < 5) { + return false; + } + return true; } - -module.exports = passwordValidator; \ No newline at end of file +module.exports = passwordValidator; diff --git a/Sprint-3/4-stretch/password-validator.test.js b/Sprint-3/4-stretch/password-validator.test.js index 8fa3089d6b..8bf75a1238 100644 --- a/Sprint-3/4-stretch/password-validator.test.js +++ b/Sprint-3/4-stretch/password-validator.test.js @@ -16,11 +16,19 @@ 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("password has at least one English uppercase letter (A-Z)", () => { + // Arrange + const password = "12345"; + // Act + const result = isValidPassword(password); + // Assert + expect(result).toEqual(true); +}); From 4ff2ef117ba9e763ba3577220a9aff65814aaae1 Mon Sep 17 00:00:00 2001 From: Tomislav Dukez Date: Fri, 3 Jul 2026 18:15:37 +0100 Subject: [PATCH 3/8] add check pass for upper case letter --- Sprint-3/4-stretch/password-validator.js | 11 ++++++++++- Sprint-3/4-stretch/password-validator.test.js | 4 ++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Sprint-3/4-stretch/password-validator.js b/Sprint-3/4-stretch/password-validator.js index 062b943209..191dded0cb 100644 --- a/Sprint-3/4-stretch/password-validator.js +++ b/Sprint-3/4-stretch/password-validator.js @@ -1,5 +1,14 @@ function passwordValidator(password) { - if (password.length < 5) { + /* To be valid, a password must: + - Have at least 5 characters. + - Have at least one English uppercase letter (A-Z) + - Have at least one English lowercase letter (a-z) + - Have at least one number (0-9) + - Have at least one of the following non-alphanumeric symbols: ("!", "#", "$", "%", ".", "*", "&") + - Must not be any previous password in the passwords array. + */ + + if (password.length < 5 || !/[A-Z]/.test(password)) { return false; } return true; diff --git a/Sprint-3/4-stretch/password-validator.test.js b/Sprint-3/4-stretch/password-validator.test.js index 8bf75a1238..e1f0192837 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 = "12345A"; // Act const result = isValidPassword(password); // Assert @@ -26,7 +26,7 @@ test("password has at least 5 characters", () => { test("password has at least one English uppercase letter (A-Z)", () => { // Arrange - const password = "12345"; + const password = "1234A"; // Act const result = isValidPassword(password); // Assert From 817489db93d5c5c2a5ad45332495f2ad25fc6711 Mon Sep 17 00:00:00 2001 From: Tomislav Dukez Date: Fri, 3 Jul 2026 18:16:53 +0100 Subject: [PATCH 4/8] add check pass for lower case letter --- Sprint-3/4-stretch/password-validator.js | 6 +++++- Sprint-3/4-stretch/password-validator.test.js | 13 +++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Sprint-3/4-stretch/password-validator.js b/Sprint-3/4-stretch/password-validator.js index 191dded0cb..9e2c04f887 100644 --- a/Sprint-3/4-stretch/password-validator.js +++ b/Sprint-3/4-stretch/password-validator.js @@ -8,7 +8,11 @@ function passwordValidator(password) { - Must not be any previous password in the passwords array. */ - if (password.length < 5 || !/[A-Z]/.test(password)) { + if ( + password.length < 5 || + !/[A-Z]/.test(password) || + !/[a-z]/.test(password) + ) { return false; } return true; diff --git a/Sprint-3/4-stretch/password-validator.test.js b/Sprint-3/4-stretch/password-validator.test.js index e1f0192837..483cceccd7 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 = "12345A"; + const password = "12345cA"; // Act const result = isValidPassword(password); // Assert @@ -26,7 +26,16 @@ test("password has at least 5 characters", () => { test("password has at least one English uppercase letter (A-Z)", () => { // Arrange - const password = "1234A"; + const password = "1234bA"; + // Act + const result = isValidPassword(password); + // Assert + expect(result).toEqual(true); +}); + +test("password has at least one English lowercase letter (a-z)", () => { + // Arrange + const password = "1234Aa"; // Act const result = isValidPassword(password); // Assert From 27ea3d0a9ebbe14f8be9cd887afd36d8e0388cf3 Mon Sep 17 00:00:00 2001 From: Tomislav Dukez Date: Fri, 3 Jul 2026 18:17:52 +0100 Subject: [PATCH 5/8] add check pass for number --- Sprint-3/4-stretch/password-validator.js | 3 ++- Sprint-3/4-stretch/password-validator.test.js | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Sprint-3/4-stretch/password-validator.js b/Sprint-3/4-stretch/password-validator.js index 9e2c04f887..84cd660c20 100644 --- a/Sprint-3/4-stretch/password-validator.js +++ b/Sprint-3/4-stretch/password-validator.js @@ -11,7 +11,8 @@ function passwordValidator(password) { if ( password.length < 5 || !/[A-Z]/.test(password) || - !/[a-z]/.test(password) + !/[a-z]/.test(password) || + !/[0-9]/.test(password) ) { return false; } diff --git a/Sprint-3/4-stretch/password-validator.test.js b/Sprint-3/4-stretch/password-validator.test.js index 483cceccd7..0fcd616ca5 100644 --- a/Sprint-3/4-stretch/password-validator.test.js +++ b/Sprint-3/4-stretch/password-validator.test.js @@ -41,3 +41,12 @@ test("password has at least one English lowercase letter (a-z)", () => { // Assert expect(result).toEqual(true); }); + +test("password has at least one number (0-9)", () => { + // Arrange + const password = "1234Aa"; + // Act + const result = isValidPassword(password); + // Assert + expect(result).toEqual(true); +}); From b2ba40c0f0c7be821aa5b1d53475d5142f93a0de Mon Sep 17 00:00:00 2001 From: Tomislav Dukez Date: Fri, 3 Jul 2026 18:22:09 +0100 Subject: [PATCH 6/8] add check pass for symbols --- Sprint-3/4-stretch/password-validator.js | 3 ++- Sprint-3/4-stretch/password-validator.test.js | 17 +++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Sprint-3/4-stretch/password-validator.js b/Sprint-3/4-stretch/password-validator.js index 84cd660c20..b2d085bbd0 100644 --- a/Sprint-3/4-stretch/password-validator.js +++ b/Sprint-3/4-stretch/password-validator.js @@ -12,7 +12,8 @@ function passwordValidator(password) { password.length < 5 || !/[A-Z]/.test(password) || !/[a-z]/.test(password) || - !/[0-9]/.test(password) + !/[0-9]/.test(password) || + !/[!#\$%\.\*&]/.test(password) ) { return false; } diff --git a/Sprint-3/4-stretch/password-validator.test.js b/Sprint-3/4-stretch/password-validator.test.js index 0fcd616ca5..89d260e311 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 = "12345cA"; + const password = "12345cA!"; // Act const result = isValidPassword(password); // Assert @@ -26,7 +26,7 @@ test("password has at least 5 characters", () => { test("password has at least one English uppercase letter (A-Z)", () => { // Arrange - const password = "1234bA"; + const password = "1234bA$"; // Act const result = isValidPassword(password); // Assert @@ -35,7 +35,7 @@ test("password has at least one English uppercase letter (A-Z)", () => { test("password has at least one English lowercase letter (a-z)", () => { // Arrange - const password = "1234Aa"; + const password = "1234Aa%"; // Act const result = isValidPassword(password); // Assert @@ -44,7 +44,16 @@ test("password has at least one English lowercase letter (a-z)", () => { test("password has at least one number (0-9)", () => { // Arrange - const password = "1234Aa"; + const password = "1234Aa&"; + // Act + const result = isValidPassword(password); + // Assert + expect(result).toEqual(true); +}); + +test("password has at least one non-alphanumeric symbol: (!, #, $, %, ., *, &)", () => { + // Arrange + const password = "1234aA#"; // Act const result = isValidPassword(password); // Assert From 071f6b37c3848b22304284b16877a6d6931ff471 Mon Sep 17 00:00:00 2001 From: Tomislav Dukez Date: Fri, 3 Jul 2026 22:01:59 +0100 Subject: [PATCH 7/8] add validation and tests historical passwords and more other tests --- Sprint-3/4-stretch/password-validator.js | 5 +- Sprint-3/4-stretch/password-validator.test.js | 54 +++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/Sprint-3/4-stretch/password-validator.js b/Sprint-3/4-stretch/password-validator.js index b2d085bbd0..4eee8c3034 100644 --- a/Sprint-3/4-stretch/password-validator.js +++ b/Sprint-3/4-stretch/password-validator.js @@ -7,13 +7,14 @@ function passwordValidator(password) { - Have at least one of the following non-alphanumeric symbols: ("!", "#", "$", "%", ".", "*", "&") - Must not be any previous password in the passwords array. */ - + const passwords = ["pa$$w0rd", "Qwerty1#", "Adm1n2#", "$3cr4t"]; if ( password.length < 5 || !/[A-Z]/.test(password) || !/[a-z]/.test(password) || !/[0-9]/.test(password) || - !/[!#\$%\.\*&]/.test(password) + !/[!#\$%\.\*&]/.test(password) || + passwords.includes(password) ) { return false; } diff --git a/Sprint-3/4-stretch/password-validator.test.js b/Sprint-3/4-stretch/password-validator.test.js index 89d260e311..091e832280 100644 --- a/Sprint-3/4-stretch/password-validator.test.js +++ b/Sprint-3/4-stretch/password-validator.test.js @@ -24,6 +24,15 @@ test("password has at least 5 characters", () => { expect(result).toEqual(true); }); +test("password with less than 5 characters is invalid", () => { + // Arrange + const password = "1Aa%"; + // Act + const result = isValidPassword(password); + // Assert + expect(result).toEqual(false); +}); + test("password has at least one English uppercase letter (A-Z)", () => { // Arrange const password = "1234bA$"; @@ -33,6 +42,15 @@ test("password has at least one English uppercase letter (A-Z)", () => { expect(result).toEqual(true); }); +test("password with no uppercase letters is invalid", () => { + // Arrange + const password = "1234ab$"; + // Act + const result = isValidPassword(password); + // Assert + expect(result).toEqual(false); +}); + test("password has at least one English lowercase letter (a-z)", () => { // Arrange const password = "1234Aa%"; @@ -42,6 +60,15 @@ test("password has at least one English lowercase letter (a-z)", () => { expect(result).toEqual(true); }); +test("password with no lowercase letters is invalid", () => { + // Arrange + const password = "1234AB$"; + // Act + const result = isValidPassword(password); + // Assert + expect(result).toEqual(false); +}); + test("password has at least one number (0-9)", () => { // Arrange const password = "1234Aa&"; @@ -51,6 +78,15 @@ test("password has at least one number (0-9)", () => { expect(result).toEqual(true); }); +test("password with no numbers is invalid", () => { + // Arrange + const password = "passWord!"; + // Act + const result = isValidPassword(password); + // Assert + expect(result).toEqual(false); +}); + test("password has at least one non-alphanumeric symbol: (!, #, $, %, ., *, &)", () => { // Arrange const password = "1234aA#"; @@ -59,3 +95,21 @@ test("password has at least one non-alphanumeric symbol: (!, #, $, %, ., *, &)", // Assert expect(result).toEqual(true); }); + +test("must not be any previous password in the passwords array.", () => { + // Arrange + const password = "pas$W0rd"; + // Act + const result = isValidPassword(password); + // Assert + expect(result).toEqual(true); +}); + +test("previous passwords in the passwords array are invalid", () => { + // Arrange + const password = "Qwerty1#"; + // Act + const result = isValidPassword(password); + // Assert + expect(result).toEqual(false); +}); From 327cc0a6638c73943482e408be7a9805667cc889 Mon Sep 17 00:00:00 2001 From: Tomislav Dukez Date: Fri, 3 Jul 2026 22:32:01 +0100 Subject: [PATCH 8/8] add card-validator code and tests --- Sprint-3/4-stretch/card-validator.js | 38 ++++++++++ Sprint-3/4-stretch/card-validator.test.js | 91 +++++++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 Sprint-3/4-stretch/card-validator.js create mode 100644 Sprint-3/4-stretch/card-validator.test.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..cd9a2d478e --- /dev/null +++ b/Sprint-3/4-stretch/card-validator.js @@ -0,0 +1,38 @@ +function validateCreditCardNumber(cardNumber) { + // Check if the card number is a positive integer. + if (typeof cardNumber !== "number" || cardNumber < 0) { + return false; + } + + const cardNumberString = String(cardNumber); + // Check if the card number has at least two different digits + const uniqueDigits = new Set(cardNumberString); + + if (uniqueDigits.size < 2) { + return false; + } + + // Check if the card number has exactly 16 digits. + if (cardNumberString.length !== 16) { + return false; + } + + // Check if the last digit is even + if (Number(cardNumberString.slice(-1)) % 2 !== 0) { + return false; + } + + // Check if the sum of all the digits is greater than 16 + const sumOfAllDigits = Array.from(cardNumberString).reduce( + (sum, digit) => sum + Number(digit), + 0 + ); + + if (sumOfAllDigits <= 16) { + return false; + } + + return true; +} + +module.exports = validateCreditCardNumber; 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..c408f05f74 --- /dev/null +++ b/Sprint-3/4-stretch/card-validator.test.js @@ -0,0 +1,91 @@ +const validateCreditCardNumber = require("./card-validator"); + +test("Number must be 16 digits, all of them must be numbers.", () => { + // Arrange + const cardNumber = 1234567890123456; + // Act + const result = validateCreditCardNumber(cardNumber); + // Assert + expect(result).toEqual(true); +}); + +test("Credit card number must have at least two different digits.", () => { + // Arrange + const cardNumber = 6262826262628262; + // Act + const result = validateCreditCardNumber(cardNumber); + // Assert + expect(result).toEqual(true); +}); + +test("Credit card with only one repeating digit is invalid.", () => { + // Arrange + const cardNumber = 8888888888888888; + // Act + const result = validateCreditCardNumber(cardNumber); + // Assert + expect(result).toEqual(false); +}); + +test("Credit card number cannot have an odd last digit.", () => { + // Arrange + const cardNumber = 1234567890123457; + // Act + const result = validateCreditCardNumber(cardNumber); + // Assert + expect(result).toEqual(false); +}); + +test("Credit card number sum of all digits cannot be less than or equal to 16.", () => { + // Arrange + const cardNumber = 1000000000000000; + // Act + const result = validateCreditCardNumber(cardNumber); + // Assert + expect(result).toEqual(false); +}); + +test("Credit card number sum of all digits must be greater than 16.", () => { + // Arrange + const cardNumber = 1234567890123452; + // Act + const result = validateCreditCardNumber(cardNumber); + // Assert + expect(result).toEqual(true); +}); + +test("Credit card number must not be negative.", () => { + // Arrange + const cardNumber = -1234567890123456; + // Act + const result = validateCreditCardNumber(cardNumber); + // Assert + expect(result).toEqual(false); +}); + +test("Credit card number must be a number.", () => { + // Arrange + const cardNumber = "1234567890123456"; + // Act + const result = validateCreditCardNumber(cardNumber); + // Assert + expect(result).toEqual(false); +}); + +test("Credit card number must have exactly 16 digits.", () => { + // Arrange + const cardNumber = 212222222212222; + // Act + const result = validateCreditCardNumber(cardNumber); + // Assert + expect(result).toEqual(false); +}); + +test("Credit card number cannot have less or more than 16 digits.", () => { + // Arrange + const cardNumber = 212222222212222; + // Act + const result = validateCreditCardNumber(cardNumber); + // Assert + expect(result).toEqual(false); +});