diff --git a/Sprint-3/1-key-implement/1-get-angle-type.js b/Sprint-3/1-key-implement/1-get-angle-type.js index 08d1f0cba..c0020bb56 100644 --- a/Sprint-3/1-key-implement/1-get-angle-type.js +++ b/Sprint-3/1-key-implement/1-get-angle-type.js @@ -7,13 +7,27 @@ // Write the code to pass the test // Then, write the next test! :) Go through this process until all the cases are implemented +// getAngleType function: +// This function takes an angle in degrees and returns the type of angle. +// I implemented 5 cases: Right, Acute, Obtuse, Straight, and Reflex angles. +// I used conditional statements (if) to check the angle's value range. + function getAngleType(angle) { if (angle === 90) return "Right angle"; + if (angle < 90) return "Acute angle"; + if (angle > 90 && angle < 180) return "Obtuse angle"; + if (angle === 180) return "Straight angle"; + if (angle > 180 && angle < 360) return "Reflex angle"; + // read to the end, complete line 36, then pass your test here } // we're going to use this helper function to make our assertions easier to read // if the actual output matches the target output, the test will pass + +// assertEquals: +// This helper function is used to check if the output from getAngleType +// matches the expected value. If not, it shows an error in the terminal. function assertEquals(actualOutput, targetOutput) { console.assert( actualOutput === targetOutput, @@ -27,6 +41,10 @@ function assertEquals(actualOutput, targetOutput) { // When the function getAngleType is called with this angle, // Then it should: + +// Tests for getAngleType: +// Each test checks one angle type and helps confirm my function is working. + // Case 1: Identify Right Angles: // When the angle is exactly 90 degrees, // Then the function should return "Right angle" @@ -43,14 +61,20 @@ assertEquals(acute, "Acute angle"); // When the angle is greater than 90 degrees and less than 180 degrees, // Then the function should return "Obtuse angle" const obtuse = getAngleType(120); +assertEquals(obtuse, "Obtuse angle"); + // ====> write your test here, and then add a line to pass the test in the function above // Case 4: Identify Straight Angles: // When the angle is exactly 180 degrees, // Then the function should return "Straight angle" +const straight = getAngleType(180); +assertEquals(straight, "Straight angle"); // ====> write your test here, and then add a line to pass the test in the function above // Case 5: Identify Reflex Angles: // When the angle is greater than 180 degrees and less than 360 degrees, // Then the function should return "Reflex angle" +const reflex = getAngleType(210); +assertEquals(reflex, "Reflex angle"); // ====> write your test here, and then add a line to pass the test in the function above \ No newline at end of file diff --git a/Sprint-3/1-key-implement/2-is-proper-fraction.js b/Sprint-3/1-key-implement/2-is-proper-fraction.js index 91583e941..91b682b62 100644 --- a/Sprint-3/1-key-implement/2-is-proper-fraction.js +++ b/Sprint-3/1-key-implement/2-is-proper-fraction.js @@ -8,7 +8,8 @@ // write one test at a time, and make it pass, build your solution up methodically function isProperFraction(numerator, denominator) { - if (numerator < denominator) return true; + if (denominator === 0) return false; + return Math.abs(numerator) < Math.abs(denominator); } // here's our helper again @@ -40,6 +41,8 @@ assertEquals(improperFraction, false); // target output: true // Explanation: The fraction -4/7 is a proper fraction because the absolute value of the numerator (4) is less than the denominator (7). The function should return true. const negativeFraction = isProperFraction(-4, 7); +assertEquals(negativeFraction, true); + // ====> complete with your assertion // Equal Numerator and Denominator check: @@ -47,7 +50,27 @@ const negativeFraction = isProperFraction(-4, 7); // target output: false // Explanation: The fraction 3/3 is not a proper fraction because the numerator is equal to the denominator. The function should return false. const equalFraction = isProperFraction(3, 3); +assertEquals(equalFraction, false) // ====> complete with your assertion // Stretch: // What other scenarios could you test for? + +// Zero numerator +// 0/5 → true (0 is less than any non-zero number) +const zeroNumerator = isProperFraction(0, 5); +assertEquals(zeroNumerator, true); + +// Negative denominator +// 3/-4 → true +const negativeDenominator = isProperFraction(3, -4); +assertEquals(negativeDenominator, true); + +// Negative improper fraction +// -5/4 → false +const negativeImproper = isProperFraction(-5, 4); +assertEquals(negativeImproper, false); + +// Zero denominator (invalid) +const zeroDenominator = isProperFraction(1, 0); +assertEquals(zeroDenominator, false); diff --git a/Sprint-3/1-key-implement/3-get-card-value.js b/Sprint-3/1-key-implement/3-get-card-value.js index aa1cc9f90..ef6b89614 100644 --- a/Sprint-3/1-key-implement/3-get-card-value.js +++ b/Sprint-3/1-key-implement/3-get-card-value.js @@ -8,7 +8,27 @@ // write one test at a time, and make it pass, build your solution up methodically // just make one change at a time -- don't rush -- programmers are deep and careful thinkers function getCardValue(card) { - if (rank === "A") return 11; + const rank = card.slice(0, -1); + + if (rank === "A") return 11; + + const numericRank = parseInt(rank); + if (!isNaN(numericRank) && numericRank >= 2 && numericRank <= 10) { + return numericRank; + } + + if (["J", "Q", "K"].includes(rank)) { + return 10; + } + + throw new Error("Invalid card rank."); +} + +function assertEquals(actualOutput, targetOutput) { + console.assert( + actualOutput === targetOutput, + `Expected ${actualOutput} to equal ${targetOutput}` + ); } // You need to write assertions for your function to check it works in different cases @@ -33,19 +53,29 @@ assertEquals(aceofSpades, 11); // When the function is called with such a card, // Then it should return the numeric value corresponding to the rank (e.g., "5" should return 5). const fiveofHearts = getCardValue("5♥"); +assertEquals(fiveofHearts, 5) // ====> write your test here, and then add a line to pass the test in the function above // Handle Face Cards (J, Q, K): // Given a card with a rank of "10," "J," "Q," or "K", // When the function is called with such a card, // Then it should return the value 10, as these cards are worth 10 points each in blackjack. +const kingOfDiamonds = getCardValue("K♦"); +assertEquals(kingOfDiamonds, 10); // Handle Ace (A): // Given a card with a rank of "A", // When the function is called with an Ace, // Then it should, by default, assume the Ace is worth 11 points, which is a common rule in blackjack. - +const aceofSpades = getCardValue("A♠"); +assertEquals(aceofSpades, 11); // Handle Invalid Cards: // Given a card with an invalid rank (neither a number nor a recognized face card), // When the function is called with such a card, // Then it should throw an error indicating "Invalid card rank." +try { + getCardValue("Z♣"); + console.error("Test failed: Expected error for invalid card rank"); +} catch (e) { + assertEquals(e.message, "Invalid card rank."); +} diff --git a/Sprint-3/2-mandatory-rewrite/1-get-angle-type.js b/Sprint-3/2-mandatory-rewrite/1-get-angle-type.js index d61254bd7..fb7dca160 100644 --- a/Sprint-3/2-mandatory-rewrite/1-get-angle-type.js +++ b/Sprint-3/2-mandatory-rewrite/1-get-angle-type.js @@ -1,6 +1,10 @@ + function getAngleType(angle) { if (angle === 90) return "Right angle"; - // replace with your completed function from key-implement + if (angle < 90) return "Acute angle"; + if (angle > 90 && angle < 180) return "Obtuse angle"; + if (angle === 180) return "Straight angle"; + if (angle > 180 && angle < 360) return "Reflex angle"; } @@ -9,8 +13,6 @@ function getAngleType(angle) { - - // Don't get bogged down in this detail // Jest uses CommonJS module syntax by default as it's quite old // We will upgrade our approach to ES6 modules in the next course module, so for now diff --git a/Sprint-3/2-mandatory-rewrite/1-get-angle-type.test.js b/Sprint-3/2-mandatory-rewrite/1-get-angle-type.test.js index b62827b7c..f822f1f6c 100644 --- a/Sprint-3/2-mandatory-rewrite/1-get-angle-type.test.js +++ b/Sprint-3/2-mandatory-rewrite/1-get-angle-type.test.js @@ -1,7 +1,7 @@ const getAngleType = require("./1-get-angle-type"); -test("should identify right angle (90°)", () => { - expect(getAngleType(90)).toEqual("Right angle"); +test('returns "Right angle" for angle equal to 90', () => { + expect(getAngleType(90)).toBe("Right angle"); }); // REPLACE the comments with the tests @@ -10,15 +10,30 @@ test("should identify right angle (90°)", () => { // Case 2: Identify Acute Angles: // When the angle is less than 90 degrees, // Then the function should return "Acute angle" +test('returns "Acute angle" for angles less than 90', () => { + expect(getAngleType(45)).toBe("Acute angle"); +}); // Case 3: Identify Obtuse Angles: // When the angle is greater than 90 degrees and less than 180 degrees, // Then the function should return "Obtuse angle" +test('returns "Obtuse angle" for angles between 90 and 180', () => { + expect(getAngleType(120)).toBe("Obtuse angle"); +}); + // Case 4: Identify Straight Angles: // When the angle is exactly 180 degrees, // Then the function should return "Straight angle" +test('returns "Straight angle" for angle equal to 180', () => { + expect(getAngleType(180)).toBe("Straight angle"); +}); + // Case 5: Identify Reflex Angles: // When the angle is greater than 180 degrees and less than 360 degrees, // Then the function should return "Reflex angle" + +test('returns "Reflex angle" for angles between 180 and 360', () => { + expect(getAngleType(270)).toBe("Reflex angle"); +}); \ No newline at end of file diff --git a/Sprint-3/2-mandatory-rewrite/2-is-proper-fraction.js b/Sprint-3/2-mandatory-rewrite/2-is-proper-fraction.js index 9836fe398..645a58513 100644 --- a/Sprint-3/2-mandatory-rewrite/2-is-proper-fraction.js +++ b/Sprint-3/2-mandatory-rewrite/2-is-proper-fraction.js @@ -1,6 +1,8 @@ + function isProperFraction(numerator, denominator) { - if (numerator < denominator) return true; - // add your completed function from key-implement here -} + if (denominator === 0) return false; + return Math.abs(numerator) < Math.abs(denominator); + } + module.exports = isProperFraction; \ No newline at end of file diff --git a/Sprint-3/2-mandatory-rewrite/2-is-proper-fraction.test.js b/Sprint-3/2-mandatory-rewrite/2-is-proper-fraction.test.js index ff1cc8173..70c4d2385 100644 --- a/Sprint-3/2-mandatory-rewrite/2-is-proper-fraction.test.js +++ b/Sprint-3/2-mandatory-rewrite/2-is-proper-fraction.test.js @@ -5,7 +5,34 @@ test("should return true for a proper fraction", () => { }); // Case 2: Identify Improper Fractions: +test("returns false for improper fraction (5/2)", () => { + expect(isProperFraction(5, 2)).toBe(false); +}); + // Case 3: Identify Negative Fractions: +test("returns true for negative proper fraction (-4/7)", () => { + expect(isProperFraction(-4, 7)).toBe(true); +}); + // Case 4: Identify Equal Numerator and Denominator: + +test("returns false for equal numerator and denominator (3/3)", () => { + expect(isProperFraction(3, 3)).toBe(false); +}); + // Zero numerator + test("returns true when numerator is 0 and denominator is non-zero", () => { + expect(isProperFraction(0, 5)).toBe(true); + expect(isProperFraction(0, -5)).toBe(true); +}); +// Zero denominator +test("returns false when denominator is 0", () => { + expect(isProperFraction(1, 0)).toBe(false); + expect(isProperFraction(0, 0)).toBe(false); +}); +// Negative denominator +test("handles negative denominators correctly", () => { + expect(isProperFraction(2, -3)).toBe(true); + expect(isProperFraction(-4, -5)).toBe(true); +}); diff --git a/Sprint-3/2-mandatory-rewrite/3-get-card-value.js b/Sprint-3/2-mandatory-rewrite/3-get-card-value.js index 0d95d3736..1d3940f81 100644 --- a/Sprint-3/2-mandatory-rewrite/3-get-card-value.js +++ b/Sprint-3/2-mandatory-rewrite/3-get-card-value.js @@ -1,5 +1,18 @@ + function getCardValue(card) { - // replace with your code from key-implement - return 11; -} + const rank = card.slice(0, -1); + + if (rank === "A") return 11; + + const numericRank = parseInt(rank); + if (!isNaN(numericRank) && numericRank >= 2 && numericRank <= 10) { + return numericRank; + } + + if (["J", "Q", "K"].includes(rank)) { + return 10; + } + + throw new Error("Invalid card rank."); + } module.exports = getCardValue; \ No newline at end of file diff --git a/Sprint-3/2-mandatory-rewrite/3-get-card-value.test.js b/Sprint-3/2-mandatory-rewrite/3-get-card-value.test.js index 03a8e2f34..0ddf41765 100644 --- a/Sprint-3/2-mandatory-rewrite/3-get-card-value.test.js +++ b/Sprint-3/2-mandatory-rewrite/3-get-card-value.test.js @@ -6,6 +6,27 @@ test("should return 11 for Ace of Spades", () => { }); // Case 2: Handle Number Cards (2-10): +test("should return numeric value for number cards", () => { + expect(getCardValue("2♦")).toEqual(2); + expect(getCardValue("10♥")).toEqual(10); + expect(getCardValue("7♣")).toEqual(7); +}); // Case 3: Handle Face Cards (J, Q, K): +test("should return 10 for Jack, Queen, and King", () => { + expect(getCardValue("J♠")).toEqual(10); + expect(getCardValue("Q♥")).toEqual(10); + expect(getCardValue("K♦")).toEqual(10); +}); + // Case 4: Handle Ace (A): +test("should return 11 for Ace of Hearts", () => { + expect(getCardValue("A♥")).toEqual(11); +}); // Case 5: Handle Invalid Cards: +test("should throw an error for invalid card rank", () => { + expect(() => getCardValue("1♠")).toThrow("Invalid card rank."); + expect(() => getCardValue("Z♣")).toThrow("Invalid card rank."); + expect(() => getCardValue("11♦")).toThrow("Invalid card rank."); + expect(() => getCardValue("")).toThrow("Invalid card rank."); +}); + diff --git a/Sprint-3/3-mandatory-practice/implement/count.js b/Sprint-3/3-mandatory-practice/implement/count.js index fce249650..7a515e801 100644 --- a/Sprint-3/3-mandatory-practice/implement/count.js +++ b/Sprint-3/3-mandatory-practice/implement/count.js @@ -1,5 +1,16 @@ -function countChar(stringOfCharacters, findCharacter) { - return 5 -} +// The test should fail because the current function always returns 5. +// function countChar(stringOfCharacters, findCharacter) { +// return 5 +// } -module.exports = countChar; \ No newline at end of file +// module.exports = countChar; +// Here the placeholder(5) is replaced to implement the function to pass the tests +function countChar(stringOfCharacters, findCharacter) { + let count = 0; + for (let char of stringOfCharacters) { + if (char === findCharacter) count++; + } + return count; + } + + module.exports = countChar; \ No newline at end of file diff --git a/Sprint-3/3-mandatory-practice/implement/count.test.js b/Sprint-3/3-mandatory-practice/implement/count.test.js index 42baf4b4b..a4c6e0f10 100644 --- a/Sprint-3/3-mandatory-practice/implement/count.test.js +++ b/Sprint-3/3-mandatory-practice/implement/count.test.js @@ -22,3 +22,11 @@ test("should count multiple occurrences of a character", () => { // And a character char that does not exist within the case-sensitive str, // When the function is called with these inputs, // Then it should return 0, indicating that no occurrences of the char were found in the case-sensitive str. + +test("should return 0 if character does not occur in the string", () => { + const str = "hello"; + const char = "z"; + const count = countChar(str, char); + expect(count).toEqual(0); +}); + diff --git a/Sprint-3/3-mandatory-practice/implement/get-ordinal-number.js b/Sprint-3/3-mandatory-practice/implement/get-ordinal-number.js index 24f528b0d..5b05aa4f5 100644 --- a/Sprint-3/3-mandatory-practice/implement/get-ordinal-number.js +++ b/Sprint-3/3-mandatory-practice/implement/get-ordinal-number.js @@ -1,5 +1,22 @@ -function getOrdinalNumber(num) { - return "1st"; -} +// function getOrdinalNumber(num) { +// return "1st"; +// } + +// module.exports = getOrdinalNumber; -module.exports = getOrdinalNumber; \ No newline at end of file +function getOrdinalNumber(num) { + const lastTwo = num % 100; + const lastDigit = num % 10; + + if (lastTwo >= 11 && lastTwo <= 13) { + return `${num}th`; + } + + if (lastDigit === 1) return `${num}st`; + if (lastDigit === 2) return `${num}nd`; + if (lastDigit === 3) return `${num}rd`; + + return `${num}th`; + } + + module.exports = getOrdinalNumber; diff --git a/Sprint-3/3-mandatory-practice/implement/get-ordinal-number.test.js b/Sprint-3/3-mandatory-practice/implement/get-ordinal-number.test.js index 6d55dfbb4..56f42b02d 100644 --- a/Sprint-3/3-mandatory-practice/implement/get-ordinal-number.test.js +++ b/Sprint-3/3-mandatory-practice/implement/get-ordinal-number.test.js @@ -11,3 +11,28 @@ const getOrdinalNumber = require("./get-ordinal-number"); test("should return '1st' for 1", () => { expect(getOrdinalNumber(1)).toEqual("1st"); }); + +test("should return '2nd' for 2", () => { + expect(getOrdinalNumber(2)).toEqual("2nd"); + }); + + test("should return '3rd' for 3", () => { + expect(getOrdinalNumber(3)).toEqual("3rd"); + }); + + test("should return '4th' for 4", () => { + expect(getOrdinalNumber(4)).toEqual("4th"); + }); + + test("should return '11th', '12th', '13th' for exceptions", () => { + expect(getOrdinalNumber(11)).toEqual("11th"); + expect(getOrdinalNumber(12)).toEqual("12th"); + expect(getOrdinalNumber(13)).toEqual("13th"); + }); + + test("should return '21st', '22nd', '23rd', '24th'", () => { + expect(getOrdinalNumber(21)).toEqual("21st"); + expect(getOrdinalNumber(22)).toEqual("22nd"); + expect(getOrdinalNumber(23)).toEqual("23rd"); + expect(getOrdinalNumber(24)).toEqual("24th"); + }); diff --git a/Sprint-3/3-mandatory-practice/implement/repeat.js b/Sprint-3/3-mandatory-practice/implement/repeat.js index 621f9bd35..75650fb3c 100644 --- a/Sprint-3/3-mandatory-practice/implement/repeat.js +++ b/Sprint-3/3-mandatory-practice/implement/repeat.js @@ -1,5 +1,15 @@ -function repeat() { - return "hellohellohello"; -} +// function repeat() { +// return "hellohellohello"; +// } -module.exports = repeat; \ No newline at end of file +// module.exports = repeat; + +function repeat(str, count) { + if (count < 0) { + throw new Error("Count must be a non-negative integer"); + } + + return str.repeat(count); + } + + module.exports = repeat; \ No newline at end of file diff --git a/Sprint-3/3-mandatory-practice/implement/repeat.test.js b/Sprint-3/3-mandatory-practice/implement/repeat.test.js index 8a4ab42ef..6b46a5cdb 100644 --- a/Sprint-3/3-mandatory-practice/implement/repeat.test.js +++ b/Sprint-3/3-mandatory-practice/implement/repeat.test.js @@ -21,12 +21,24 @@ test("should repeat the string count times", () => { // When the repeat function is called with these inputs, // Then it should return the original str without repetition, ensuring that a count of 1 results in no repetition. +test("should return original string if count is 1", () => { + expect(repeat("hello", 1)).toEqual("hello"); + }); + // case: Handle Count of 0: // Given a target string str and a count equal to 0, // When the repeat function is called with these inputs, // Then it should return an empty string, ensuring that a count of 0 results in an empty output. +test("should return empty string if count is 0", () => { + expect(repeat("hello", 0)).toEqual(""); + }); + // case: Negative Count: // Given a target string str and a negative integer count, // When the repeat function is called with these inputs, // Then it should throw an error or return an appropriate error message, as negative counts are not valid. +test("should throw an error if count is negative", () => { + expect(() => repeat("hello", -2)).toThrow("Count must be a non-negative integer"); + }); + diff --git a/Sprint-3/4-stretch-investigate/credit-card validator2.js b/Sprint-3/4-stretch-investigate/credit-card validator2.js new file mode 100644 index 000000000..033722999 --- /dev/null +++ b/Sprint-3/4-stretch-investigate/credit-card validator2.js @@ -0,0 +1,25 @@ +function validateCreditCard(cardNumber) { + const trimmed = cardNumber.toString().trim(); + + // Must be exactly 16 digits + if (trimmed.length !== 16) return false; + + // Must be all numeric + if (!/^\d+$/.test(trimmed)) return false; + + // Must contain at least two different digits + const uniqueDigits = new Set(trimmed); + if (uniqueDigits.size < 2) return false; + + // Last digit must be even + const lastDigit = parseInt(trimmed[trimmed.length - 1]); + if (lastDigit % 2 !== 0) return false; + + // Sum of all digits must be > 16 + const sum = trimmed.split('').reduce((acc, digit) => acc + parseInt(digit), 0); + if (sum <= 16) return false; + + return true; + } + + module.exports = validateCreditCard; \ No newline at end of file diff --git a/Sprint-3/4-stretch-investigate/credit-card-validator.test b/Sprint-3/4-stretch-investigate/credit-card-validator.test new file mode 100644 index 000000000..7126faa98 --- /dev/null +++ b/Sprint-3/4-stretch-investigate/credit-card-validator.test @@ -0,0 +1,26 @@ +const validateCreditCard = require("./credit-card-validator-2"); + +test("validates a correct card number: 9999777788880000", () => { + expect(validateCreditCard("9999777788880000")).toBe(true); +}); + +test("validates a correct card number: 6666666666661666", () => { + expect(validateCreditCard("6666666666661666")).toBe(true); +}); + +test("rejects card with invalid characters: a92332119c011112", () => { + expect(validateCreditCard("a92332119c011112")).toBe(false); +}); + +test("rejects card with only one digit repeated: 4444444444444444", () => { + expect(validateCreditCard("4444444444444444")).toBe(false); +}); + +test("rejects card with sum less than or equal to 16: 1111111111111110", () => { + expect(validateCreditCard("1111111111111110")).toBe(false); +}); + +test("rejects card ending in an odd digit: 6666666666666661", () => { + expect(validateCreditCard("6666666666666661")).toBe(false); +}); + diff --git a/Sprint-3/4-stretch-investigate/find.js b/Sprint-3/4-stretch-investigate/find.js index c7e79a2f2..98431d87e 100644 --- a/Sprint-3/4-stretch-investigate/find.js +++ b/Sprint-3/4-stretch-investigate/find.js @@ -10,9 +10,28 @@ function find(str, char) { return -1; } +function find(str, char) { + let index = 0; // Start checking from the first character in the string + + // Loop through each character until the end of the string + while (index < str.length) { + // Check if the current character matches the one we're looking for + if (str[index] === char) { + return index; // If found, return its position + } + index++; // Move to the next character + } + + return -1; // If the character wasn't found, return -1 +} + + console.log(find("code your future", "u")); console.log(find("code your future", "z")); +console.log(find("code your future", "u")); // Should return 7 (first "u") +console.log(find("code your future", "z")); // Should return -1 (not found) + // The while loop statement allows us to do iteration - the repetition of a certain number of tasks according to some condition // See the docs https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while diff --git a/Sprint-3/4-stretch-investigate/password-validator.js b/Sprint-3/4-stretch-investigate/password-validator.js index b55d527db..fface382b 100644 --- a/Sprint-3/4-stretch-investigate/password-validator.js +++ b/Sprint-3/4-stretch-investigate/password-validator.js @@ -1,6 +1,34 @@ +// function passwordValidator(password) { +// return password.length < 5 ? false : true +// } + + +// module.exports = passwordValidator; + +// List of previously used passwords that are no longer allowed +const oldPasswords = ["Password1!", "12345aA!", "Admin123!"]; + function passwordValidator(password) { - return password.length < 5 ? false : true -} + // Rule 1: Password must be at least 5 characters long + if (password.length < 5) return false; + + // Rule 2: Must have at least one uppercase letter (A–Z) + const hasUpperCase = /[A-Z]/.test(password); + // Rule 3: Must have at least one lowercase letter (a–z) + const hasLowerCase = /[a-z]/.test(password); + + // Rule 4: Must include at least one number (0–9) + const hasNumber = /[0-9]/.test(password); + + // Rule 5: Must include at least one special symbol from the list: !, #, $, %, ., *, & + const hasSymbol = /[!#$%.*&]/.test(password); + + // Rule 6: Password must NOT match any in the list of old passwords + const isNotOldPassword = !oldPasswords.includes(password); + + // Final check: return true only if all rules are passed + return hasUpperCase && hasLowerCase && hasNumber && hasSymbol && isNotOldPassword; +} module.exports = passwordValidator; \ No newline at end of file diff --git a/Sprint-3/4-stretch-investigate/password-validator.test.js b/Sprint-3/4-stretch-investigate/password-validator.test.js index 8fa3089d6..92b5866a4 100644 --- a/Sprint-3/4-stretch-investigate/password-validator.test.js +++ b/Sprint-3/4-stretch-investigate/password-validator.test.js @@ -14,13 +14,53 @@ To be valid, a password must: You must breakdown this problem in order to solve it. Find one test case first and get that working */ + const isValidPassword = require("./password-validator"); -test("password has at least 5 characters", () => { - // Arrange + +test("fails if only numbers are used", () => { const password = "12345"; - // Act const result = isValidPassword(password); - // Assert + expect(result).toEqual(false); +}); + +test("valid password passes all rules", () => { + const password = "Good1!"; + const result = isValidPassword(password); expect(result).toEqual(true); -} -); \ No newline at end of file +}); + +test("fails if password is too short", () => { + const password = "A1!a"; + const result = isValidPassword(password); + expect(result).toEqual(false); +}); + +test("fails if missing uppercase letter", () => { + const password = "good1!"; + const result = isValidPassword(password); + expect(result).toEqual(false); +}); + +test("fails if missing lowercase letter", () => { + const password = "GOOD1!"; + const result = isValidPassword(password); + expect(result).toEqual(false); +}); + +test("fails if missing number", () => { + const password = "Good!"; + const result = isValidPassword(password); + expect(result).toEqual(false); +}); + +test("fails if missing symbol", () => { + const password = "Good12"; + const result = isValidPassword(password); + expect(result).toEqual(false); +}); + +test("fails if password is in oldPasswords list", () => { + const password = "Password1!"; + const result = isValidPassword(password); + expect(result).toEqual(false); +}); \ No newline at end of file