From c0d6c3b1ed1278f9f47e90a25079e55336b3610c Mon Sep 17 00:00:00 2001
From: tmnaqeesha <tmnaqeesha@users.noreply.github.com>
Date: Thu, 15 May 2025 01:33:22 +0200
Subject: [PATCH] fix: Enhance code, javadoc and comments

---
 src/opinion/SocialNetwork.java     | 174 ++++++++++++++---------------
 src/tests/ConsultItemBookTest.java | 139 ++++++++++++++++-------
 src/tests/ReviewItemBookTest.java  | 150 ++++++++++++++++++-------
 3 files changed, 284 insertions(+), 179 deletions(-)

diff --git a/src/opinion/SocialNetwork.java b/src/opinion/SocialNetwork.java
index 7a1c9b6..7a5ba3f 100644
--- a/src/opinion/SocialNetwork.java
+++ b/src/opinion/SocialNetwork.java
@@ -1,13 +1,8 @@
 package opinion;
 
-import java.util.LinkedList;
+import exceptions.*;
 
-import exceptions.BadEntryException;
-import exceptions.ItemBookAlreadyExistsException;
-import exceptions.ItemFilmAlreadyExistsException;
-import exceptions.MemberAlreadyExistsException;
-import exceptions.NotItemException;
-import exceptions.NotMemberException;
+import java.util.LinkedList;
 
 /**
  * Skeleton for the SocialNetwork
@@ -43,7 +38,6 @@ public class SocialNetwork implements ISocialNetwork {
      */
     @Override
     public int nbMembers() {
-        // TODO Auto-generated method stub
         return nbmembers;
     }
 
@@ -65,8 +59,7 @@ public class SocialNetwork implements ISocialNetwork {
      */
     @Override
     public int nbBooks() {
-        // TODO Auto-generated method stub
-        return listBook.size();
+        return nbbooks;
     }
 
     /**
@@ -87,18 +80,18 @@ public class SocialNetwork implements ISocialNetwork {
     /**
      * Validates the format of a user's login and password (not empty or too short)
      *
-     * @param login    the login to be validated
+     * @param login the login to be validated
      * @param password the password to be validated
      * @return true if login and password are valid
      * @throws BadEntryException if either login or password is invalid
      */
-    public boolean validateuser(String login, String password) throws BadEntryException {
+    public boolean validateUser(String login, String password) throws BadEntryException {
         boolean result = false;
-        if (login == null  || login.length() <= 1) {
-            throw new BadEntryException("login is null or empty");
+        if (login == null || login.length() <= 1) {
+            throw new BadEntryException("Error: Login is null or empty");
         }
         if (password == null || password.length() < 4) {
-            throw new BadEntryException("password is null or empty");
+            throw new BadEntryException("Error: Password is null or empty");
         }
         return true;
     }
@@ -106,7 +99,7 @@ public class SocialNetwork implements ISocialNetwork {
     /**
      * Authenticates a user's login and password
      *
-     * @param login    the login of the user
+     * @param login the login of the user
      * @param password the password of the user
      * @return true if password corresponds to registered login, false if wrong password
      */
@@ -127,10 +120,9 @@ public class SocialNetwork implements ISocialNetwork {
      * @return true if book does not exist yet in system, false if already exists
      * @throws BadEntryException if title is empty or too short
      */
-    public boolean validatebook(String title) throws BadEntryException {
-        boolean result = false;
-        if (title == null || title.length() <= 1) {
-            throw new BadEntryException("title is null or empty");
+    public boolean validateBook(String title) throws BadEntryException {
+        if (title == null || title.trim().length() <= 1) {
+            throw new BadEntryException("Error: Title is null or too short");
         }
         for (Book b : listBook) {
             if (b.compareTitle(title)) {
@@ -143,18 +135,18 @@ public class SocialNetwork implements ISocialNetwork {
     /**
      * Adds a new member to the social network.
      *
-     * @param login    the new member's login
+     * @param login the new member's login
      * @param password the new member's password
-     * @param profile  a free String describing the new member's profile
-     * @throws BadEntryException            if parameter is null or too short
+     * @param profile a free String describing the new member's profile
+     * @throws BadEntryException if parameter is null or too short
      * @throws MemberAlreadyExistsException if login already exists
      */
     @Override
     public void addMember(String login, String password, String profile) throws BadEntryException, MemberAlreadyExistsException {
         if (profile == null) {
-            throw new BadEntryException("profile is null or empty");
+            throw new BadEntryException("Error: Profile is null or empty");
         }
-        validateuser(login, password);
+        validateUser(login, password);
         if (memberRegister(login)) {
             throw new MemberAlreadyExistsException();
         }
@@ -163,32 +155,37 @@ public class SocialNetwork implements ISocialNetwork {
         nbmembers++;
     }
 
+    @Override
+    public void addItemFilm(String login, String password, String title, String kind, String director, String scriptwriter, int duration)
+            throws BadEntryException, NotMemberException, ItemFilmAlreadyExistsException {
+    }
+    
     /**
      * Adds a new book to the social network.
      *
-     * @param login    login of the member adding the book
+     * @param login login of the member adding the book
      * @param password password of the member adding the book
-     * @param title    the new book's title
-     * @param kind     the new book's kind
-     * @param author   the new book's author
-     * @param nbPages  number of pages of the new book's
-     * @throws BadEntryException              if any input is invalid (empty or number pages equal or less than 0)
-     * @throws NotMemberException             if login or password is wrong
+     * @param title the new book's title
+     * @param kind the new book's kind
+     * @param author the new book's author
+     * @param nbPages number of pages of the new book's
+     * @throws BadEntryException if any input is invalid (empty or number pages equal or less than 0)
+     * @throws NotMemberException if login or password is wrong
      * @throws ItemBookAlreadyExistsException if book already exists in system
      */
     @Override
     public void addItemBook(String login, String password, String title, String kind, String author, int nbPages) throws BadEntryException, NotMemberException, ItemBookAlreadyExistsException {
-        validateuser(login, password);
+        validateUser(login, password);
         if (title == null || title.trim().isEmpty())
-            throw new BadEntryException("Error: Invalid title.");
+            throw new BadEntryException("Error: Title is null or empty");
         if (kind == null || kind.trim().isEmpty())
-            throw new BadEntryException("Error: Invalid kind.");
+            throw new BadEntryException("Error: Kind is null or empty");
         if (author == null || author.trim().isEmpty())
-            throw new BadEntryException("Error: Invalid author.");
+            throw new BadEntryException("Error: Author is null or empty");
         if (nbPages <= 0)
-            throw new BadEntryException("Error: Invalid number of pages.");
+            throw new BadEntryException("Error: Page number is null or less");
         if (!authenticateUser(login, password))
-            throw new NotMemberException("Error: User doesn't exist");
+            throw new NotMemberException("Error: Invalid login or password");
         for (Book b : listBook) {
             if (b.compareTitle(title)) {
                 throw new ItemBookAlreadyExistsException();
@@ -200,64 +197,41 @@ public class SocialNetwork implements ISocialNetwork {
     }
 
     @Override
-    public void addItemFilm(String login, String password, String title, String kind, String director, String scriptwriter, int duration)
-            throws BadEntryException, NotMemberException, ItemFilmAlreadyExistsException {
-    }
-
-    @Override
-    public float reviewItemFilm(String login, String password, String title,
-                                float mark, String comment) throws BadEntryException, NotMemberException, NotItemException {
+    public float reviewItemFilm(String login, String password, String title, float mark, String comment)
+            throws BadEntryException, NotMemberException, NotItemException {
         // TODO Auto-generated method stub
         return 0;
     }
 
     /**
-     * Displays a whole list of registered members
      *
-     * @return list of registered members
+     * @param login login of the member adding the review
+     * @param password password of the member adding the review
+     * @param title the reviewed book's title
+     * @param mark the mark given by the member for this book
+     * @param comment the comment given by the member for this book
+     * @return average mark of current book
+     * @throws BadEntryException if any input is invalid (mark is out of range)
+     * @throws NotMemberException if login or password is wrong
+     * @throws NotItemException if book doesn't exist
      */
-    public String toString() {
-        if (listMember.isEmpty()) {
-            return "There are currently no registered members :(";
-        }
-        String ret = "\nRegistered members:\n";
-        int counter = 1;
-        for (Member m : listMember) {
-            ret += counter + ". " + m.toString() + "\n";
-            counter++;
-        }
-        return ret.trim();
-    }
-
-
     @Override
-    public float reviewItemBook(String login, String password, String title,
-                                float mark, String comment) throws BadEntryException,
-            NotMemberException, NotItemException {
-
-        // Validate user
-        validateuser(login, password);
-
+    public float reviewItemBook(String login, String password, String title, float mark, String comment)
+            throws BadEntryException, NotMemberException, NotItemException {
+        validateUser(login, password);
         if (comment == null) {
-            throw new BadEntryException("Comment cannot be null.");
+            throw new BadEntryException("Error: Comment is null");
         }
-
         if (mark < 0.0f || mark > 5.0f) {
-            throw new BadEntryException("Mark must be between 0.0 and 5.0.");
+            throw new BadEntryException("Error: Mark must be between 0.0 and 5.0");
         }
-
-        // Verify existence of book
-        boolean bookExists = validatebook(title);
+        boolean bookExists = validateBook(title);
         if (!bookExists) {
-            throw new NotItemException("Book not found.");
+            throw new NotItemException("Error: Book not found");
         }
-
-        // Member authentication
         if (!authenticateUser(login, password)) {
-            throw new NotMemberException("Invalid login or password.");
+            throw new NotMemberException("Error: Invalid login or password");
         }
-
-        // Search book
         Book targetBook = null;
         for (Book b : listBook) {
             if (b.compareTitle(title)) {
@@ -265,37 +239,52 @@ public class SocialNetwork implements ISocialNetwork {
                 break;
             }
         }
-
         if (targetBook == null) {
-            throw new NotItemException("Book not found.");
+            throw new NotItemException("Error: Book not found");
         }
-
-        // Add or replace a review
         targetBook.addOrUpdateReview(login.trim(), mark, comment);
-
-        // Returns the new average mark
         return targetBook.getAverageMark();
     }
 
-    
+    /**
+     *
+     * @param title title of searched item(s)
+     * @return the search result of book or film added
+     * @throws BadEntryException if any input is invalid (title is empty or too short)
+     */
     @Override
     public LinkedList<String> consultItems(String title) throws BadEntryException {
         if (title == null || title.trim().length() <= 1) {
-            throw new BadEntryException("Title is null or too short.");
+            throw new BadEntryException("Error: Title is null or too short");
         }
-
         String formattedTitle = title.trim().toLowerCase();
         LinkedList<String> result = new LinkedList<>();
-
         for (Book b : listBook) {
             if (b.getTitle().toLowerCase().contains(formattedTitle)) {
                 result.add(b.toString());
             }
         }
-
         return result;
     }
 
+    /**
+     * Displays a whole list of registered members
+     *
+     * @return list of registered members
+     */
+    public String toString() {
+        if (listMember.isEmpty()) {
+            return "There are currently no registered members :(";
+        }
+        String ret = "\nRegistered members:\n";
+        int counter = 1;
+        for (Member m : listMember) {
+            ret += counter + ". " + m.toString() + "\n";
+            counter++;
+        }
+        return ret.trim();
+    }
+    
     /**
      * @param args
      */
@@ -303,5 +292,4 @@ public class SocialNetwork implements ISocialNetwork {
         // TODO Auto-generated method stub
 
     }
-
-}
\ No newline at end of file
+}
diff --git a/src/tests/ConsultItemBookTest.java b/src/tests/ConsultItemBookTest.java
index fdf87b7..825e35d 100644
--- a/src/tests/ConsultItemBookTest.java
+++ b/src/tests/ConsultItemBookTest.java
@@ -1,79 +1,132 @@
 package tests;
 
-import opinion.SocialNetwork;
+import exceptions.*;
 import opinion.ISocialNetwork;
-import exceptions.BadEntryException;
-import exceptions.ItemBookAlreadyExistsException;
-import exceptions.MemberAlreadyExistsException;
-import exceptions.NotMemberException;
+import opinion.SocialNetwork;
 
 import java.util.LinkedList;
 
+/**
+ * Tests for the <i>consultItems()</i> method.
+ */
 public class ConsultItemBookTest {
 
-    private static int nbTests = 0;
-    private static int nbErrors = 0;
-
-    private static void displaySuccess(String message) {
-        System.out.println("Test passed: " + message);
-    }
-
-    private static void displayError(String message) {
-        System.out.println("Test failed: " + message);
-        nbErrors++;
-    }
-
-    private static void testExpectedException(ISocialNetwork sn, String title, Class<?> expectedException, String testId) {
-        nbTests++;
+    /**
+     * Checks that consultItems() throws the expected exception.
+     *
+     * @param sn the social network
+     * @param title the title to consult
+     * @param expectedException the expected exception class (with any type of class)
+     * @param testId the test identifier
+     * @return 0 if test is OK, 1 if not OK
+     */
+    private static int checkConsultItemBookException(ISocialNetwork sn, String title, Class<?> expectedException, String testId) {
         try {
             sn.consultItems(title);
-            displayError("[" + testId + "] Expected exception " + expectedException.getSimpleName() + " but none was thrown");
+            System.out.println("Err " + testId + " : Expected exception " + expectedException.getSimpleName() + " was not thrown");
+            return 1;
         } catch (Exception e) {
             if (e.getClass().equals(expectedException)) {
-                displaySuccess("[" + testId + "] Correctly threw " + expectedException.getSimpleName());
+                return 0;
             } else {
-                displayError("[" + testId + "] Unexpected exception: " + e);
+                System.out.println("Err " + testId + " : Unexpected exception " + e);
+                e.printStackTrace();
+                return 1;
             }
         }
     }
 
-    private static void testConsultResult(ISocialNetwork sn, String title, int expectedSize, String testId) {
-        nbTests++;
+    /**
+     * Checks that consultItems() returns the expected number of results.
+     *
+     * @param sn the social network
+     * @param title the title to consult
+     * @param expectedSize the expected number of returned results
+     * @param testId the test identifier
+     * @return 0 if test is OK, 1 if not OK
+     */
+    private static int checkConsultItemBookResult(ISocialNetwork sn, String title, int expectedSize, String testId) {
         try {
             LinkedList<String> results = sn.consultItems(title);
             if (results.size() == expectedSize) {
-                displaySuccess("[" + testId + "] Returned expected number of results: " + expectedSize);
+                return 0;
             } else {
-                displayError("[" + testId + "] Expected " + expectedSize + " but got " + results.size());
+                System.out.println("Err " + testId + " : Expected " + expectedSize + " result(s) but got " + results.size());
+                return 1;
             }
         } catch (Exception e) {
-            displayError("[" + testId + "] Unexpected exception: " + e);
+            System.out.println("Err " + testId + " : Unexpected exception " + e);
+            e.printStackTrace();
+            return 1;
         }
     }
 
-    public static void main(String[] args) {
+    /**
+     * Main test for consultItems:
+     * Checks if the method throws BadEntryException in non-nominal conditions
+     * Checks if the method works correctly in nominal conditions
+     *
+     * @return a summary of the performed tests
+     */
+    public static TestReport test() {
         ISocialNetwork sn = new SocialNetwork();
+        int nbTests = 0;
+        int nbErrors = 0;
 
         try {
-            sn.addMember("user1", "pass1234", "profile");
-            sn.addItemBook("user1", "pass1234", "Don Quijote", "Novela", "Cervantes", 800);
-            sn.addItemBook("user1", "pass1234", "El Principito", "Fábula", "Saint-Exupéry", 100);
-            sn.addItemBook("user1", "pass1234", "Principios de Física", "Ciencia", "Tipler", 1200);
-        } catch (Exception e) {
+            sn.addMember("User1", "pass1234", "profile");
+            sn.addItemBook("User1", "pass1234", "Don Quijote", "Novela", "Cervantes", 800);
+            sn.addItemBook("User1", "pass1234", "El Principito", "Fábula", "Saint-Exupéry", 100);
+            sn.addItemBook("User1", "pass1234", "Principios de Física", "Ciencia", "Tipler", 1200);
+        } catch (BadEntryException | MemberAlreadyExistsException | NotMemberException |
+                 ItemBookAlreadyExistsException e) {
             System.out.println("Setup failed: " + e);
-            return;
+            e.printStackTrace();
+            return null;
         }
 
-        // Exception cases
-        testExpectedException(sn, null, BadEntryException.class, "3.8");
-        testExpectedException(sn, " ", BadEntryException.class, "3.9");
-        testExpectedException(sn, "a", BadEntryException.class, "3.10");
+        System.out.println("Testing consultItems()");
+
+        // Non-nominal scenarios
 
-        // Success cases
-        testConsultResult(sn, "princip", 2, "3.11"); // It returns two books "El principito" and "Principios de la fisica"
-        testConsultResult(sn, "DON", 1, "3.12");     // test case-sensitive
-        testConsultResult(sn, "XYZ", 0, "3.13");     // no results
+        // Test 3.11 : Uninstantiated title
+        nbTests++;
+        nbErrors += checkConsultItemBookException(sn, null, BadEntryException.class, "3.11");
+
+        // Test 3.12 : Invalid title (only containing a space)
+        nbTests++;
+        nbErrors += checkConsultItemBookException(sn, " ", BadEntryException.class, "3.12");
 
-        System.out.println("\nConsultItemBookTest: " + nbTests + " tests run, " + nbErrors + " errors.");
+        // Test 3.13 : Invalid title (too short)
+        nbTests++;
+        nbErrors += checkConsultItemBookException(sn, "a", BadEntryException.class, "3.13");
+
+        // Nominal scenarios
+
+        // Test 3.14 : Matches "El Principito" and "Principios de Física"
+        nbTests++;
+        nbErrors += checkConsultItemBookResult(sn, "princip", 2, "3.14");
+
+        // Test 3.15 : Matches "Don Quijote" case-insensitively
+        nbTests++;
+        nbErrors += checkConsultItemBookResult(sn, "DON", 1, "3.15");
+
+        // Test 3.16 : No matches
+        nbTests++;
+        nbErrors += checkConsultItemBookResult(sn, "XYZ", 0, "3.16");
+
+        // Print a summary of the tests and return test results
+        try {
+            TestReport tr = new TestReport(nbTests, nbErrors);
+            System.out.println("ConsultItemBookTest : " + tr);
+            return tr;
+        } catch (NotTestReportException e) {
+            System.out.println("Unexpected error in ConsultItemBookTest test code - Can't return valuable test results");
+            return null;
+        }
+    }
+
+    public static void main(String[] args) {
+        test();
     }
 }
diff --git a/src/tests/ReviewItemBookTest.java b/src/tests/ReviewItemBookTest.java
index 744af09..327b417 100644
--- a/src/tests/ReviewItemBookTest.java
+++ b/src/tests/ReviewItemBookTest.java
@@ -1,79 +1,143 @@
 package tests;
 
-import opinion.SocialNetwork;
+import exceptions.BadEntryException;
+import exceptions.NotItemException;
+import exceptions.NotMemberException;
+import exceptions.NotTestReportException;
 import opinion.ISocialNetwork;
-import exceptions.*;
+import opinion.SocialNetwork;
 
+/**
+ * Tests for the SocialNetwork.<i>reviewItemBook()</i> method.
+ */
 public class ReviewItemBookTest {
 
-    private static int nbTests = 0;
-    private static int nbErrors = 0;
-
-    private static void displaySuccess(String message) {
-        System.out.println("Test passed: " + message);
-    }
-
-    private static void displayError(String message) {
-        System.out.println("Test failed: " + message);
-        nbErrors++;
-    }
-
-    private static void testExpectedAverage(ISocialNetwork sn, String login, String password, String title,
-                                            float mark, String comment, float expectedAverage, String testId) {
-        nbTests++;
+    /**
+     * Checks that reviewItemBook() returns the expected average after adding a review.
+     *
+     * @param sn              the social network
+     * @param login           the login of the reviewing member
+     * @param password        the password of the reviewing member
+     * @param title           the title of the book
+     * @param mark            the rating given
+     * @param comment         the comment provided
+     * @param expectedAverage the expected average rating
+     * @param testId          the test identifier
+     * @return 0 if test is OK, 1 if not OK
+     */
+    private static int checkReviewItemBookAverage(ISocialNetwork sn, String login, String password, String title, float mark, String comment, float expectedAverage, String testId) {
         try {
             float result = sn.reviewItemBook(login, password, title, mark, comment);
             if (Math.abs(result - expectedAverage) < 0.01f) {
-                displaySuccess("[" + testId + "] Average = " + result);
+                return 0;
             } else {
-                displayError("[" + testId + "] Expected " + expectedAverage + " but got " + result);
+                System.out.println("Err " + testId + " : Expected average " + expectedAverage + " but got " + result);
+                return 1;
             }
         } catch (Exception e) {
-            displayError("[" + testId + "] Unexpected exception: " + e);
+            System.out.println("Err " + testId + " : Unexpected exception " + e);
+            e.printStackTrace();
+            return 1;
         }
     }
 
-    private static void testExpectedException(ISocialNetwork sn, String login, String password, String title,
-                                              float mark, String comment, Class<?> expectedException, String testId) {
-        nbTests++;
+    /**
+     * Checks that reviewItemBook() throws the expected exception in invalid situations.
+     *
+     * @param sn                the social network
+     * @param login             the login of the reviewer
+     * @param password          the reviewer's password
+     * @param title             the book's title
+     * @param mark              the rating
+     * @param comment           the review comment
+     * @param expectedException the expected exception class
+     * @param testId            the test identifier
+     * @return 0 if test is OK, 1 if not OK
+     */
+    private static int checkReviewItemBookException(ISocialNetwork sn, String login, String password, String title, float mark, String comment, Class<?> expectedException, String testId) {
         try {
             sn.reviewItemBook(login, password, title, mark, comment);
-            displayError("[" + testId + "] Expected exception " + expectedException.getSimpleName() + " but none was thrown");
+            System.out.println("Err " + testId + " : Expected exception " + expectedException.getSimpleName() + " was not thrown");
+            return 1;
         } catch (Exception e) {
             if (e.getClass().equals(expectedException)) {
-                displaySuccess("[" + testId + "] Correctly threw " + expectedException.getSimpleName());
+                return 0;
             } else {
-                displayError("[" + testId + "] Unexpected exception: " + e);
+                System.out.println("Err " + testId + " : Unexpected exception " + e);
+                e.printStackTrace();
+                return 1;
             }
         }
     }
 
+    /**
+     * Main test method for reviewItemBook:
+     * Tests both nominal and non-nominal scenarios.
+     *
+     * @return a summary of the performed tests
+     */
     public static TestReport test() {
         ISocialNetwork sn = new SocialNetwork();
+        int nbTests = 0;
+        int nbErrors = 0;
 
         try {
-            sn.addMember("ana", "pass123", "casual reader");
-            sn.addMember("luis", "1234pass", "fantasy reader");
-            sn.addItemBook("ana", "pass123", "El Hobbit", "Fantasía", "J.R.R. Tolkien", 300);
+            sn.addMember("Neva", "pass123", "casual reader");
+            sn.addMember("Maryam", "1234pass", "fantasy reader");
+            sn.addItemBook("Neva", "pass123", "El Hobbit", "Fantasía", "J.R.R. Tolkien", 300);
         } catch (Exception e) {
-            System.out.println("Setup failed: " + e.getMessage());
+            System.out.println("Setup failed: " + e);
+            e.printStackTrace();
             return null;
         }
 
-        // --- Sucess cases ---
-        testExpectedAverage(sn, "ana", "pass123", "El Hobbit", 4.0f, "So good", 4.0f, "1.1");
-        testExpectedAverage(sn, "luis", "1234pass", "El Hobbit", 5.0f, "excelent!", 4.5f, "1.2");
-        testExpectedAverage(sn, "ana", "pass123", "El Hobbit", 3.0f, "good but long", 4.0f, "1.3");
+        System.out.println("Testing reviewItemBook()");
+
+        // Non-nominal cases
+
+        // Test 3.1 : Member doesn't exist
+        nbTests++;
+        nbErrors += checkReviewItemBookException(sn, "Mario", "nopass", "El Hobbit", 4.0f, "Hola", NotMemberException.class, "3.1");
+
+        // Test 3.2 : Book title doesn't exist
+        nbTests++;
+        nbErrors += checkReviewItemBookException(sn, "Neva", "pass123", "Book X", 3.0f, "Does not exist", NotItemException.class, "3.2");
+
+        // Test 3.3 : Invalid mark (out of range)
+        nbTests++;
+        nbErrors += checkReviewItemBookException(sn, "Neva", "pass123", "El Hobbit", 6.0f, "Out of range", BadEntryException.class, "3.3");
+
+        // Test 3.4 : Invalid login (empty)
+        nbTests++;
+        nbErrors += checkReviewItemBookException(sn, "", "pass123", "El Hobbit", 4.0f, "Fantastic book", BadEntryException.class, "3.4");
+
+        // Test 3.5 : Invalid password (too short)
+        nbTests++;
+        nbErrors += checkReviewItemBookException(sn, "Neva", "a", "El Hobbit", 4.0f, "Fantastic book", BadEntryException.class, "3.5");
+
+        // Test 3.6 : Invalid book title (empty)
+        nbTests++;
+        nbErrors += checkReviewItemBookException(sn, "Neva", "pass123", "", 4.0f, "Fantastic book", BadEntryException.class, "3.6");
 
-        // --- Cases with exception ---
-        testExpectedException(sn, "mario", "nopass", "El Hobbit", 4.0f, "Hola", NotMemberException.class, "3.1");
-        testExpectedException(sn, "ana", "pass123", "Book X", 3.0f, "Does not exist", NotItemException.class, "3.2");
-        testExpectedException(sn, "ana", "pass123", "El Hobbit", 6.0f, "Out of range", BadEntryException.class, "3.3");
-        testExpectedException(sn, "", "pass123", "El Hobbit", 4.0f, "Fantastic book", BadEntryException.class, "3.4");
-        testExpectedException(sn, "ana", "a", "El Hobbit", 4.0f, "Fantastic book", BadEntryException.class, "3.5");
-        testExpectedException(sn, "ana", "pass123", "", 4.0f, "Fantastic book", BadEntryException.class, "3.6");
-        testExpectedException(sn, "ana", "pass123", "El Hobbit", 4.0f, null, BadEntryException.class, "3.7");
+        // Test 3.7 : Uninstantiated comment
+        nbTests++;
+        nbErrors += checkReviewItemBookException(sn, "Neva", "pass123", "El Hobbit", 4.0f, null, BadEntryException.class, "3.7");
+
+        // Nominal cases
+
+        // Test 3.1 : First review for "El Hobbit", expects average mark of 4.0
+        nbTests++;
+        nbErrors += checkReviewItemBookAverage(sn, "Neva", "pass123", "El Hobbit", 4.0f, "So good", 4.0f, "3.8");
+
+        // Test 3.2 : Second review from another user, expects average of (4.0 + 5.0) ÷ 2 = 4.5
+        nbTests++;
+        nbErrors += checkReviewItemBookAverage(sn, "Maryam", "1234pass", "El Hobbit", 5.0f, "Perfect", 4.5f, "3.9");
+
+        // Test 3.3: Update Neva's review to 3.0, expects average of (3.0 + 5.0) ÷ 2 = 4.0
+        nbTests++;
+        nbErrors += checkReviewItemBookAverage(sn, "Neva", "pass123", "El Hobbit", 3.0f, "Good but too long", 4.0f, "3.11");
 
+        // Print a summary of the tests and return test results
         try {
             TestReport report = new TestReport(nbTests, nbErrors);
             System.out.println("ReviewItemBookTest : " + report);
@@ -87,4 +151,4 @@ public class ReviewItemBookTest {
     public static void main(String[] args) {
         test();
     }
-}
+}
\ No newline at end of file
-- 
GitLab