diff --git a/out/production/infrastructureLogicielleClient/opinion/Book.class b/out/production/infrastructureLogicielleClient/opinion/Book.class
index dbdc2cd776a1d7fb9146f3653746c2aa23291368..d090638588fb800270805a9a52c290a1398613ea 100644
Binary files a/out/production/infrastructureLogicielleClient/opinion/Book.class and b/out/production/infrastructureLogicielleClient/opinion/Book.class differ
diff --git a/out/production/infrastructureLogicielleClient/opinion/SocialNetwork.class b/out/production/infrastructureLogicielleClient/opinion/SocialNetwork.class
index f72caf53502252cc68a317e97eb5f24e42b6d421..2fa5842a0df30e57043402766fb26b3dd70f2198 100644
Binary files a/out/production/infrastructureLogicielleClient/opinion/SocialNetwork.class and b/out/production/infrastructureLogicielleClient/opinion/SocialNetwork.class differ
diff --git a/out/production/infrastructureLogicielleClient/tests/AddMemberTest.class b/out/production/infrastructureLogicielleClient/tests/AddMemberTest.class
index 428db0695063dcca3c3a0991857b6b6341ad027e..b1d6375ffa627f698c13550ef3e0df492265dab6 100644
Binary files a/out/production/infrastructureLogicielleClient/tests/AddMemberTest.class and b/out/production/infrastructureLogicielleClient/tests/AddMemberTest.class differ
diff --git a/src/opinion/Book.java b/src/opinion/Book.java
index bc3c4a6902bae07ca41408087c16e64934753158..4ac8218fc20b26400bbef747a4523d616f11a65b 100644
--- a/src/opinion/Book.java
+++ b/src/opinion/Book.java
@@ -10,15 +10,15 @@ import java.util.LinkedList;
  * @version 1.0
  * @since 1.0
  */
-public class Book {
+public class Book extends Item{
 
     /**
      * Declaration of private class variables : book title, kind and author
      */
 
-    private String title, kind, author, comment;
+    private String author, comment;
     private int nbPages;
-    private LinkedList<Review> reviews = new LinkedList<>();
+
 
     /**
      * <b>Initialization of private variables with constructor</b>
@@ -29,14 +29,13 @@ public class Book {
      * @param nbPages The number of pages of the book
      */
     public Book(String title, String kind, String author, int nbPages) {
-        this.title = title;
-        this.kind = kind;
-        this.author = author;
+        super(title, kind);
+        this.author = author.trim();
         this.nbPages = nbPages;
     }
 
     /**
-     * <b>Return the title of the book</b>
+     * Return the title of the book
      *
      * @return book's title
      */
@@ -45,7 +44,7 @@ public class Book {
     }
 
     /**
-     * <b>Return the kind of the book</b>
+     * Return the kind of the book
      *
      * @return book's kind
      */
@@ -54,7 +53,7 @@ public class Book {
     }
 
     /**
-     * <b>Retrieve the author of the book</b>
+     * Return the author of the book
      *
      * @return book's author
      */
@@ -63,7 +62,7 @@ public class Book {
     }
 
     /**
-     * <b>Return the number of pages of the book</b>
+     * Return the number of pages of the book
      *
      * @return book's page number
      */
@@ -71,48 +70,20 @@ public class Book {
         return this.nbPages;
     }
 
-    /**
-     * <b>Identify if the current book's <i>title</i> is similar as another book</b>
-     *
-     * @param title2 other's book's title
-     * @return true if same, false if different
-     */
-    public boolean compareTitle(String title2) {
-        String formattedTitle = this.title.toUpperCase().trim();
-        String formattedTitle2 = title2.toUpperCase().trim();
-        return formattedTitle.equals(formattedTitle2);
-    }
-    public void addOrUpdateReview(String login, float mark, String comment) {
-        for (Review r : reviews) {
-            if (r.getReviewerLogin().equalsIgnoreCase(login)) {
-                r.setMark(mark);
-                r.setComment(comment);
-                return;
-            }
-        }
-        reviews.add(new Review(login, mark, comment));
-    }
 
-    public float getAverageMark() {
-        if (reviews.isEmpty()) return 0f;
-        float total = 0f;
-        for (Review r : reviews) {
-            total += r.getMark();
-        }
-        return total / reviews.size();
-    }
+
     /**
-     * <b>String function to display the details of a book</b>
+     * String function to display the details of a book
      *
      * @return the book's details
      */
     public String toString() {
         String text = "Book : " + getTitle() + "\nKind : " + getKind() + "\nAuthor : " + getAuthor() + "\nNumber of pages : " + getNbPages()+"\nOverall note: "+getAverageMark() +"\nReviews";
-        int counter = 1;
-        for (Review r : reviews) {
-            text += counter + ". " + r.getReviewerLogin() + "\t" + r.getMark() + "\t" + r.getComment();
-            counter++;
-        }
+        //int counter = 1;
+        //for (Review r : reviews) {
+        //    text += counter + ". " + r.getReviewerLogin() + "\t" + r.getMark() + "\t" + r.getComment();
+        //    counter++;
+        //}
         return text;
     }
 }
diff --git a/src/opinion/Film.java b/src/opinion/Film.java
new file mode 100644
index 0000000000000000000000000000000000000000..6dd31b12ce3be43b8df82378af03cacf31bbab6c
--- /dev/null
+++ b/src/opinion/Film.java
@@ -0,0 +1,32 @@
+package opinion;
+
+public class Film extends Item {
+    private String director;
+    private String scenarist;
+    private int duration;
+
+    public Film(String title, String kind, String director, String scenarist, int duration) {
+        super(title, kind);
+        this.director = director.trim();
+        this.scenarist = scenarist.trim();
+        this.duration = duration;
+    }
+
+    public String getDirector() {
+        return director;
+    }
+
+    public String getScenarist() {
+        return scenarist;
+    }
+
+    public int getDuration() {
+        return duration;
+    }
+
+    @Override
+    public String toString() {
+        return "Film Title: " + title + "\nKind: " + kind + "\nDirector: " + director +
+                "\nScenarist: " + scenarist + "\nDuration: " + duration + " minutes";
+    }
+}
diff --git a/src/opinion/Item.java b/src/opinion/Item.java
new file mode 100644
index 0000000000000000000000000000000000000000..ceaeba516f2027dffdf9ce3c9f84e37066ed8273
--- /dev/null
+++ b/src/opinion/Item.java
@@ -0,0 +1,60 @@
+package opinion;
+
+import java.util.LinkedList;
+
+public abstract class Item {
+    protected String title;
+    protected String kind;
+
+    private LinkedList<Review> reviews = new LinkedList<>();
+
+    public Item(String title, String kind) {
+        this.title = title.trim();
+        this.kind = kind.trim();
+        this.reviews = new LinkedList<>();
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public String getKind() {
+        return kind;
+    }
+
+    public LinkedList<Review> getReviews() {
+        return reviews;
+    }
+
+    public void addReview(Review review) {
+        reviews.add(review);
+    }
+
+    public abstract String toString();
+
+    public boolean compareTitle(String title2) {
+        if (this.title == null || title2 == null) return false;
+        String formattedTitle = this.title.trim().toUpperCase();
+        String formattedTitle2 = title2.trim().toUpperCase();
+        return formattedTitle.equals(formattedTitle2);
+    }
+    public void addOrUpdateReview(String login, float mark, String comment) {
+        for (Review r : reviews) {
+            if (r.getReviewerLogin().equalsIgnoreCase(login)) {
+                r.setMark(mark);
+                r.setComment(comment);
+                return;
+            }
+        }
+        reviews.add(new Review(login, mark, comment));
+    }
+    public float getAverageMark() {
+        if (reviews.isEmpty()) return 0f;
+        float total = 0f;
+        for (Review r : reviews) {
+            total += r.getMark();
+        }
+        return total / reviews.size();
+    }
+}
+
diff --git a/src/opinion/SocialNetwork.java b/src/opinion/SocialNetwork.java
index 7a5ba3fce88bd6c3c704944a38e57b1f5e2895fb..eb49d9e71c09fb6cdf01a40a912966712b973fc0 100644
--- a/src/opinion/SocialNetwork.java
+++ b/src/opinion/SocialNetwork.java
@@ -19,7 +19,8 @@ public class SocialNetwork implements ISocialNetwork {
     private int nbmembers, nbbooks;
     private LinkedList<Book> listBook;
     private Book book;
-
+    private LinkedList<Film> listFilm;
+    private int nbfilms;
 
     /**
      * Constructs new SocialNetwork instance with empty member list.
@@ -27,8 +28,10 @@ public class SocialNetwork implements ISocialNetwork {
     public SocialNetwork() {
         listMember = new LinkedList<Member>();
         listBook = new LinkedList<Book>();
+        listFilm = new LinkedList<Film>();
         nbmembers = 0;
         nbbooks = 0;
+        nbfilms = 0;
     }
 
     /**
@@ -41,16 +44,8 @@ public class SocialNetwork implements ISocialNetwork {
         return nbmembers;
     }
 
-    /**
-     * Returns number of films.
-     *
-     * @return 0
-     */
-    @Override
-    public int nbFilms() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
+
+
 
     /**
      * Returns number of books.
@@ -155,9 +150,66 @@ 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 {
+
+        validateUser(login, password);
+
+        if (title == null || title.trim().isEmpty())
+            throw new BadEntryException("Error: Title is null or empty");
+        if (kind == null || kind.trim().isEmpty())
+            throw new BadEntryException("Error: Kind is null or empty");
+        if (director == null || director.trim().isEmpty())
+            throw new BadEntryException("Error: Director is null or empty");
+        if (scriptwriter == null || scriptwriter.trim().isEmpty())
+            throw new BadEntryException("Error: Scriptwriter is null or empty");
+        if (duration <= 0)
+            throw new BadEntryException("Error: Duration must be > 0");
+        if (!authenticateUser(login, password))
+            throw new NotMemberException("Error: Invalid login or password");
+
+        for (Film f : listFilm) {
+            if (f.compareTitle(title)) {
+                throw new ItemFilmAlreadyExistsException();
+            }
+        }
+
+        Film film = new Film(title.trim(), kind.trim(), director.trim(), scriptwriter.trim(), duration);
+        listFilm.add(film);
+        nbfilms++;
+    }
+    /**
+     * Returns number of films.
+     *
+     * @return 0
+     */
+    @Override
+    public int nbFilms() {
+        return nbfilms;
+    }
+
+    @Override
+    public float reviewItemFilm(String login, String password, String title, float mark, String comment)
+            throws BadEntryException, NotMemberException, NotItemException {
+
+        validateUser(login, password);
+        if (comment == null)
+            throw new BadEntryException("Error: Comment is null");
+        if (mark < 0.0f || mark > 5.0f)
+            throw new BadEntryException("Error: Mark must be between 0.0 and 5.0");
+        if (!authenticateUser(login, password))
+            throw new NotMemberException("Error: Invalid login or password");
+
+        for (Film f : listFilm) {
+            if (f.compareTitle(title)) {
+                f.addOrUpdateReview(login.trim(), mark, comment);
+                return f.getAverageMark();
+            }
+        }
+
+        throw new NotItemException("Error: Film not found");
     }
     
     /**
@@ -196,12 +248,7 @@ public class SocialNetwork implements ISocialNetwork {
         nbbooks++;
     }
 
-    @Override
-    public float reviewItemFilm(String login, String password, String title, float mark, String comment)
-            throws BadEntryException, NotMemberException, NotItemException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
+
 
     /**
      *
@@ -257,13 +304,24 @@ public class SocialNetwork implements ISocialNetwork {
         if (title == null || title.trim().length() <= 1) {
             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());
             }
         }
+
+        for (Film f : listFilm) {
+            if (f.getTitle().toLowerCase().contains(formattedTitle)
+                    || f.getDirector().toLowerCase().contains(formattedTitle)
+                    || f.getScenarist().toLowerCase().contains(formattedTitle)) {
+                result.add(f.toString());
+            }
+        }
+
         return result;
     }
 
diff --git a/src/tests/AddItemBookTest.java b/src/tests/AddItemBookTest.java
index 07dc4b9c15e3d872b6cc30a4e119164352c8f3f5..bbc9aa0e6873a8ba42297efe973af99ac37bb2f5 100644
--- a/src/tests/AddItemBookTest.java
+++ b/src/tests/AddItemBookTest.java
@@ -1,12 +1,8 @@
 package tests;
 
+import exceptions.*;
 import opinion.ISocialNetwork;
 import opinion.SocialNetwork;
-import exceptions.BadEntryException;
-import exceptions.MemberAlreadyExistsException;
-import exceptions.NotMemberException;
-import exceptions.ItemBookAlreadyExistsException;
-import exceptions.NotTestReportException;
 
 /**
  * Tests for the SocialNetwork.<i>addItemBook()</i> method.
diff --git a/src/tests/AddItemFilmTest.java b/src/tests/AddItemFilmTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..2b5722c4e381d9e6594080ef935f73732c1ddc76
--- /dev/null
+++ b/src/tests/AddItemFilmTest.java
@@ -0,0 +1,138 @@
+package tests;
+
+import exceptions.BadEntryException;
+import exceptions.ItemFilmAlreadyExistsException;
+import exceptions.MemberAlreadyExistsException;
+import exceptions.NotTestReportException;
+import opinion.ISocialNetwork;
+import opinion.SocialNetwork;
+
+/**
+ * Tests for the SocialNetwork.<i>addItemFilm()</i> method.
+ */
+public class AddItemFilmTest {
+
+    /**
+     * Check that the method addItemFilm() throws the expected exception.
+     *
+     * @param sn                the <i>ISocialNetwork</i> to test
+     * @param login             login of the member
+     * @param password          password of the member
+     * @param title             title of the film
+     * @param kind              kind of the film
+     * @param director          director of the film
+     * @param scenarist         scenarist of the film
+     * @param duration          duration of the film (in minutes)
+     * @param testId            id of the test
+     * @param expectedException error message to display if test fails
+     * @return 0 if the exception was correctly thrown, 1 otherwise
+     */
+    private static int checkAddItemFilmException(ISocialNetwork sn, String login, String password, String title, String kind, String director, String scenarist, int duration, String testId, Class<?> expectedException) {
+        try {
+            sn.addItemFilm(login, password, title, kind, director, scenarist, duration);
+            System.out.println("Err " + testId + " : Expected exception " + expectedException.getSimpleName() + " was not thrown");
+            return 1;
+        } catch (Exception e) {
+            if (e.getClass().equals(expectedException)) {
+                return 0;
+            } else {
+                System.out.println("Err " + testId + " : Unexpected exception " + e);
+                e.printStackTrace();
+                return 1;
+            }
+        }
+
+    }
+
+    /**
+     * Check that the method addItemFilm() works in a nominal case.
+     *
+     * @param sn        the <i>ISocialNetwork</i> to test
+     * @param login     login of the member
+     * @param password  password of the member
+     * @param title     title of the film
+     * @param kind      kind of the film
+     * @param director  director of the film
+     * @param scenarist scenarist of the film
+     * @param duration  duration of the film (in minutes)
+     * @param testId    id of the test
+     * @return 0 if film was correctly added, 1 otherwise
+     */
+    private static int checkAddItemFilmSuccess(ISocialNetwork sn, String login, String password, String title,
+                                               String kind, String director, String scenarist, int duration,
+                                               String testId) {
+        try {
+            sn.addItemFilm(login, password, title, kind, director, scenarist, duration);
+            return 0;
+        } catch (Exception e) {
+            System.out.println("Err " + testId + " : Unexpected exception " + e);
+            return 1;
+        }
+    }
+
+    /**
+     * Main test for addItemFilm:
+     * Checks if the method throws BadEntryException or itemFilmAlreadyExistsException 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("taylorSwift", "password", "profile2");
+        } catch (BadEntryException | MemberAlreadyExistsException e) {
+            System.out.println("Err : Unexpected exception " + e);
+            e.printStackTrace();
+        }
+
+        // Non-nominal scenarios except 4.5
+
+        // Test 4.1: Login is null
+        nbTests++;
+        nbErrors += checkAddItemFilmException(sn, null, "password", "Inception", "Sci-Fi", "Nolan", "Nolan", 120,
+                "4.1", BadEntryException.class);
+
+        // Test 4.2: Password is too short
+        nbTests++;
+        nbErrors += checkAddItemFilmException(sn, "taylorSwift", "123", "Inception", "Sci-Fi", "Nolan", "Nolan", 120,
+                "4.2", BadEntryException.class);
+
+        // Test 4.3: Title is null
+        nbTests++;
+        nbErrors += checkAddItemFilmException(sn, "taylorSwift", "password", null, "Sci-Fi", "Nolan", "Nolan", 120,
+                "4.3", BadEntryException.class);
+
+        // Test 4.4: Duration is negative
+        nbTests++;
+        nbErrors += checkAddItemFilmException(sn, "taylorSwift", "password", "Inception", "Sci-Fi", "Nolan", "Nolan", -10,
+                "4.4", BadEntryException.class);
+
+        // Test 4.5: Valid film creation (Nominal)
+        nbTests++;
+        nbErrors += checkAddItemFilmSuccess(sn, "taylorSwift", "password", "Inception", "Sci-Fi", "Nolan", "Nolan", 120,
+                "4.5");
+
+        // Test 4.6: Duplicate film creation
+        nbTests++;
+        nbErrors += checkAddItemFilmException(sn, "taylorSwift", "password", "Inception", "Sci-Fi", "Nolan", "Nolan", 120,
+                "4.6", ItemFilmAlreadyExistsException.class);
+
+        try {
+            TestReport tr = new TestReport(nbTests, nbErrors);
+            System.out.println("AddItemBookTest : " + tr);
+            return tr;
+        } catch (NotTestReportException e) {
+            System.out.println("Unexpected error in AddItemBookTest test code - Can't return valuable test results");
+            return null;
+        }
+    }
+
+    public static void main(String[] args) {
+        test();
+    }
+}
\ No newline at end of file
diff --git a/src/tests/ConsultItemFilmTest.java b/src/tests/ConsultItemFilmTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..59bb273ce08851a7741864f3fbaf709deb7b2b5a
--- /dev/null
+++ b/src/tests/ConsultItemFilmTest.java
@@ -0,0 +1,75 @@
+package tests;
+
+import exceptions.*;
+import opinion.ISocialNetwork;
+import opinion.SocialNetwork;
+
+import java.util.LinkedList;
+
+public class ConsultItemFilmTest {
+
+    private static int checkConsultItemFilmException(ISocialNetwork sn, String title, Class<?> expectedException, String testId) {
+        try {
+            sn.consultItems(title);
+            System.out.println("Err " + testId + " : Expected exception " + expectedException.getSimpleName() + " was not thrown");
+            return 1;
+        } catch (Exception e) {
+            if (e.getClass().equals(expectedException)) {
+                System.out.println("Test " + testId + " passed (caught expected " + expectedException.getSimpleName() + ")");
+                return 0;
+            } else {
+                System.out.println("Err " + testId + " : Unexpected exception " + e);
+                e.printStackTrace();
+                return 1;
+            }
+        }
+    }
+
+    private static int checkConsultItemFilmResult(ISocialNetwork sn, String title, int expectedSize, String testId) {
+        try {
+            LinkedList<String> results = sn.consultItems(title);
+            if (results.size() == expectedSize) {
+                System.out.println("Test " + testId + " passed.");
+                return 0;
+            } else {
+                System.out.println("Err " + testId + " : Expected " + expectedSize + " result(s) but got " + results.size());
+                return 1;
+            }
+        } catch (Exception e) {
+            System.out.println("Err " + testId + " : Unexpected exception " + e);
+            e.printStackTrace();
+            return 1;
+        }
+    }
+
+    public static void main(String[] args) {
+        ISocialNetwork sn = new SocialNetwork();
+        int nbTests = 0;
+        int nbErrors = 0;
+
+        try {
+            sn.addMember("cinefan", "securepass", "film fan");
+            sn.addItemFilm("cinefan", "securepass", "Interstellar", "Sci-Fi", "Christopher Nolan", "Jonathan Nolan", 169);
+            sn.addItemFilm("cinefan", "securepass", "Inception", "Thriller", "Christopher Nolan", "Christopher Nolan", 148);
+        } catch (Exception e) {
+            System.out.println("Setup failed: " + e);
+            return;
+        }
+
+        // Nominal tests
+        nbTests++;
+        nbErrors += checkConsultItemFilmResult(sn, "Inception", 1, "3.1");
+
+        nbTests++;
+        nbErrors += checkConsultItemFilmResult(sn, "nolan", 2, "3.2");
+
+        nbTests++;
+        nbErrors += checkConsultItemFilmResult(sn, "Unknown Film", 0, "3.3");
+
+        // Non-nominal test (expects exception)
+        nbTests++;
+        nbErrors += checkConsultItemFilmException(sn, "", BadEntryException.class, "3.4");
+
+        System.out.println("\nConsultItemFilmTest summary: " + nbErrors + " error(s) out of " + nbTests + " test(s).");
+    }
+}
diff --git a/src/tests/ReviewItemFilmTest.java b/src/tests/ReviewItemFilmTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..c54a6c4d94ab8799ffa46172a6edec04d612a69c
--- /dev/null
+++ b/src/tests/ReviewItemFilmTest.java
@@ -0,0 +1,124 @@
+package tests;
+
+import exceptions.BadEntryException;
+import exceptions.NotItemException;
+import exceptions.NotMemberException;
+import exceptions.NotTestReportException;
+import opinion.ISocialNetwork;
+import opinion.SocialNetwork;
+
+/**
+ * Tests for the SocialNetwork.<i>reviewItemFilm()</i> method.
+ */
+public class ReviewItemFilmTest {
+
+    /**
+     * Checks that reviewItemFilm() returns the expected average after adding a review.
+     */
+    private static int checkReviewItemFilmAverage(ISocialNetwork sn, String login, String password, String title,
+                                                  float mark, String comment, float expectedAverage, String testId) {
+        try {
+            float avg = sn.reviewItemFilm(login, password, title, mark, comment);
+            if (Math.abs(avg - expectedAverage) < 0.01) {
+                return 0;
+            } else {
+                System.out.println("Err " + testId + " : Expected average " + expectedAverage + " but got " + avg);
+                return 1;
+            }
+        } catch (Exception e) {
+            System.out.println("Err " + testId + " : Unexpected exception " + e);
+            e.printStackTrace();
+            return 1;
+        }
+    }
+
+    /**
+     * Checks that reviewItemFilm() throws the expected exception.
+     */
+    private static int checkReviewItemFilmException(ISocialNetwork sn, String login, String password, String title,
+                                                    float mark, String comment, Class<?> expectedException, String testId) {
+        try {
+            sn.reviewItemFilm(login, password, title, mark, comment);
+            System.out.println("Err " + testId + " : Expected exception " + expectedException.getSimpleName() + " was not thrown");
+            return 1;
+        } catch (Exception e) {
+            if (e.getClass().equals(expectedException)) {
+                return 0;
+            } else {
+                System.out.println("Err " + testId + " : Unexpected exception " + e);
+                e.printStackTrace();
+                return 1;
+            }
+        }
+    }
+
+    /**
+     * Launch all tests for reviewItemFilm().
+     */
+    private static TestReport test() {
+        ISocialNetwork sn = new SocialNetwork();
+        int nbTests = 0;
+        int nbErrors = 0;
+
+        try {
+            sn.addMember("Neva", "pass123", "casual reader");
+            sn.addMember("Maryam", "1234pass", "fantasy reader");
+            sn.addItemFilm("Neva", "pass123", "Inception", "Sci-Fi", "Nolan", "Nolan", 120);
+        } catch (Exception e) {
+            System.out.println("Setup failed: " + e);
+            e.printStackTrace();
+            return null;
+        }
+
+        System.out.println("Testing reviewItemFilm()");
+
+        // Test 4.7: login is null
+        nbTests++;
+        nbErrors += checkReviewItemFilmException(sn, null, "pass123", "Inception", 4.0f, "Great!",
+                BadEntryException.class, "4.7");
+
+        // Test 4.8: password is too short
+        nbTests++;
+        nbErrors += checkReviewItemFilmException(sn, "Maryam", "12", "Inception", 4.0f, "Nice!",
+                BadEntryException.class, "4.8");
+
+        // Test 4.9: title is null
+        nbTests++;
+        nbErrors += checkReviewItemFilmException(sn, "Maryam", "1234pass", null, 4.0f, "Awesome!",
+                NotItemException.class, "4.9");
+
+        // Test 4.10: member does not exist
+        nbTests++;
+        nbErrors += checkReviewItemFilmException(sn, "unknown", "password", "Inception", 4.0f, "Not bad",
+                NotMemberException.class, "4.10");
+
+        // Test 4.11: item does not exist
+        nbTests++;
+        nbErrors += checkReviewItemFilmException(sn, "Maryam", "1234pass", "Unknown Film", 4.0f, "Great!",
+                NotItemException.class, "4.11");
+
+        // Test 4.12: first valid review, expect average 4.0
+        nbTests++;
+        nbErrors += checkReviewItemFilmAverage(sn, "Maryam", "1234pass", "Inception", 4.0f, "Great film!",
+                4.0f, "4.12");
+
+        // Test 4.13: second review, expect average 3.0
+        nbTests++;
+        nbErrors += checkReviewItemFilmAverage(sn, "Neva", "pass123", "Inception", 2.0f, "Okay film",
+                3.0f, "4.13");
+
+        // Print a summary of the tests and return test results
+        try {
+            TestReport report = new TestReport(nbTests, nbErrors);
+            System.out.println("ReviewItemBookTest : " + report);
+            return report;
+        } catch (NotTestReportException e) {
+            System.out.println("Failed to create TestReport");
+            return null;
+        }
+    }
+
+    public static void main(String[] args) {
+        test();
+    }
+}