From fe631f15124d60f1aeb34d4b333b14202c08f4fc Mon Sep 17 00:00:00 2001
From: MASSY FERNANDEZ Neva Aracely
 <neva-aracely.massy-fernandez@imt-atlantique.net>
Date: Mon, 12 May 2025 12:10:44 +0200
Subject: [PATCH] add: ReviewItemBook, Test, and ReviewClass

---
 .../opinion/Book.class                        | Bin 1831 -> 2913 bytes
 .../opinion/SocialNetwork.class               | Bin 5776 -> 6358 bytes
 src/opinion/Book.java                         |  21 ++++
 src/opinion/Review.java                       |  33 +++++++
 src/opinion/SocialNetwork.java                |  44 ++++++++-
 src/tests/ReviewItemBookTest.java             |  90 ++++++++++++++++++
 6 files changed, 186 insertions(+), 2 deletions(-)
 create mode 100644 src/opinion/Review.java
 create mode 100644 src/tests/ReviewItemBookTest.java

diff --git a/out/production/infrastructureLogicielleClient/opinion/Book.class b/out/production/infrastructureLogicielleClient/opinion/Book.class
index 8dfdf984bf75a2ed66860015a00782fa24b141a7..f0972e96f383f2128c50e18372491c4e3843f9c3 100644
GIT binary patch
literal 2913
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

delta 1010
zcmaDTww#aa)W2Q(7#J8_7=kBq>C133a4>MPGjQ=Ra5L~QGVtUVWaee&=jl7;=Vwn`
zDDTd}z{kVD50YZZ&df^zDHr5n5CRFXC6<<C<QIX2M0glP8N?VF*z=MC64O(Q85tNo
zxfmoEB-t6Hco?J^WG1sST1iSU$nh}9GsrM9u#^;K=7JO`@-QedC{K=JR8HYwP~~Az
z1Icovr<R0dmgJ;zF>o+w@GxkC1liM5OT07lQb1zbJPbM@G0ybV5=XEjK%#m)4EhWP
zj0{}qsU?0ecQ9*cdI~WxFc|SL7&Dkmp37XqWTi3rEVIhw`^+Mfn^+<y2Q!IHzQLk5
zIhWO((QWclRx>^iE(T8qFLnlRkRG4OFIg`$`cK}=ro|G-$RIcQ0Gr%oPIjJp4hAL$
z1_o9JCQ!&RFfcHIf(c9uG4OzCQz$LUAjZJJz|O$Pz{+68z{p_Ez`)SJz{J4Hz`!7-
zwVi=cOM5E=yOz#Y23{@QtqcNMqAXh(gg1iCumGuHU}Iol5Mf|p5M|(G5M$tD5N8ms
z2L&&KB!eXb1A_^~C<ZGAYX%UI0y~Kjtd*aE2kcNOP^2+1gT+7&Vqsteg*MbV`V5Q=
zAoZ+TTNv0kz-?v&3o3#w;Q_N*p_VY#gQ5kCZeDcVTG(`h;tz{v0d&pAST*Z27%<dB
z!V%fw!fVhRZi7{~4TCMz>P!YE1{MYe21$^ww=sxsW03XLhR}XGy4x5O5C-yrgU*eC
zo57tyn8Aa=vYvr~K?|ZA8YB!1k_>hXpkU%=;A5}{hr2KX8-oJ_4+Ap;BZDJ@4Afo+
z22kiTFo<bwV^GoB#-OgXjX_Im8-wmH215o0^e_lS@`V`GE@lQ*C$MLo8C)0`7&sUh
a8Qd8d8C)5B85kJ27#JD+7y=lA7$gDpcXJ5<

diff --git a/out/production/infrastructureLogicielleClient/opinion/SocialNetwork.class b/out/production/infrastructureLogicielleClient/opinion/SocialNetwork.class
index 63caec3114c6cff4ec8a5d44055e4672e8b70dec..37acf0e72b0dad6549446276e819536d633cdb5d 100644
GIT binary patch
delta 2214
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
ZF)%VbVR*y9z`(`8$ncioJ;O%^NdUD_uRs6*

delta 1636
zcmca+I6;@|)W2Q(7#J8_818K3TF=JJ&M<ZJV|E8dUY@eVoXnKOlGLR9{Orw&oWYEY
zJ13WNEo5eAI51g`U2d`%xANp*?)TE?85!6Z8TAwxx%k-_E^;wkVz|uCaD|6q62sNW
zu{@U<Z%j7i)ndFgIfmERe+mN|0}}%u13v>J!!!m41}28-3``7Z4C!FDD1#W7mW0wm
zNa|)VFfp_-v@<X;2rw`*urjbQFfz=Xe2>?Ran@u}K6&Zc3=9lB42%p645|!s80IoC
zFfcOAV~_=_^5+w)pT)oc*2BP{&wx<N3RgQHqLzVyL5G16Yz`Ci8n9~+I<1g&GQo8&
zfa^4Z>g3Sc!XU7XK?+H~64*#rBm+3$2E;O0ft|_5@4`51vNyl9I>><v49pDD48jZx
z8PXY;85kIhq3S`bMGT7>7#WsK?&X(coH=<pza!(U$uIfkgFyPU7+4q>7!2U54HzJ*
zL1If87Bet0Ffr&cEMr*Cz|63Ofq{XOf#nYaA0sC>C&LN`1_l-eMg}_uCWZ=zD6pfV
z1R}CQAt1%T#=yW(#2~{^%wWJ!!r;JA%HYIM&fv;W0rnKgS{Vj4uya8UaECj<9qs^k
z28aVd*77hg|6$-@XHd5M#lXbC$gq;Zih+q?=44sHP{vu4iv`uAV4g8y;AU9G&<^&N
z3*1x}hSlIeU}A6rdxi<@89@eCuxI`-u(LBL%YlqWc#4r>4MQ^6k}rZOjI$<33TgYp
zEMZ^>h8rCWcW^M&!64bS42z*5#=^kFCk75IP-3=Yh+|-6SjVs)Z1QEH*Nn3!?-ve^
z1eqMfz`-zuK@jYG4h9B>TW~vW!R@#Ox8oMrOQ5*E#jt^4G1$Ym7&bC2W?%*D-NYcq
zz{ap-a<+(MJ;+xa49pC643!LZ42%q$8Mc7zXJB9`WME(b*~PdKE%lxS#}mj&pu7Re
zBOn$mc`(8q!U%T=Bitd33|pZNVPx3GP`?<Q92gn4Gl(&;gTn&mnjH*`47(V1LtO(3
z8&JYw;$Da5oXcS6*n!P~WhPL80CNr#+&N5e=P)tsVb}`_7X=0;hJ9f7AP2;L21bT{
z219VVT_hULIBW7RQSEwAM1WGK9)kcpb-F<#LV&@H;UG922{D*39AXe-fTSY<24>!W
z3_R=%#*FL?%D))Y7#JB26XB`1n4YQ!`<p0V;q=rIhNBG33^N%R7;M1#mw|y}Hv@a*
zb_UK3VADYv6jUHGFnk6(0OSo&DgZ@t9RoN)KynKxv>-VgQu-ca;AA+?Z~_!!3=9m~
z;8K%;0VC=B0h<abUKtrqGMr*yU|?oA4YvCX!&$Hej0_hT7#YqnTw`Eh;9_88xXy5s
I;WmRL0P0=@2><{9

diff --git a/src/opinion/Book.java b/src/opinion/Book.java
index e2b8f61..88f4112 100644
--- a/src/opinion/Book.java
+++ b/src/opinion/Book.java
@@ -1,5 +1,7 @@
 package opinion;
 
+import java.util.LinkedList;
+
 /**
  * This class allows us to create books and to register new books
  */
@@ -8,6 +10,7 @@ public class Book {
     //Declaration of private class variables
     private String title, kind, author, comment;
     private int nbPages;
+    private LinkedList<Review> reviews = new LinkedList<>();
 
     /**
      * Initialization of private variables with constructor
@@ -71,7 +74,25 @@ public class Book {
         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();
+    }
     /**
      * String function to display the details of a book
      *
diff --git a/src/opinion/Review.java b/src/opinion/Review.java
new file mode 100644
index 0000000..e66dcd2
--- /dev/null
+++ b/src/opinion/Review.java
@@ -0,0 +1,33 @@
+package opinion;
+
+public class Review {
+    private String reviewerLogin;
+    private float mark;
+    private String comment;
+
+    public Review(String reviewerLogin, float mark, String comment) {
+        this.reviewerLogin = reviewerLogin;
+        this.mark = mark;
+        this.comment = comment;
+    }
+
+    public String getReviewerLogin() {
+        return reviewerLogin;
+    }
+
+    public float getMark() {
+        return mark;
+    }
+
+    public void setMark(float mark) {
+        this.mark = mark;
+    }
+
+    public String getComment() {
+        return comment;
+    }
+
+    public void setComment(String comment) {
+        this.comment = comment;
+    }
+}
\ No newline at end of file
diff --git a/src/opinion/SocialNetwork.java b/src/opinion/SocialNetwork.java
index 3a0fd69..239e01b 100644
--- a/src/opinion/SocialNetwork.java
+++ b/src/opinion/SocialNetwork.java
@@ -229,12 +229,52 @@ public class SocialNetwork implements ISocialNetwork {
         return ret.trim();
     }
 
+
     @Override
     public float reviewItemBook(String login, String password, String title,
                                 float mark, String comment) throws BadEntryException,
             NotMemberException, NotItemException {
-        // TODO Auto-generated method stub
-        return 0;
+
+        // Validate user
+        validateuser(login, password);
+
+        if (comment == null) {
+            throw new BadEntryException("Comment cannot be null.");
+        }
+
+        if (mark < 0.0f || mark > 5.0f) {
+            throw new BadEntryException("Mark must be between 0.0 and 5.0.");
+        }
+
+        // Verify existence of book
+        boolean bookExists = validatebook(title);
+        if (!bookExists) {
+            throw new NotItemException("Book not found.");
+        }
+
+        // Member authentication
+        if (!authenticateUser(login, password)) {
+            throw new NotMemberException("Invalid login or password.");
+        }
+
+        // Search book
+        Book targetBook = null;
+        for (Book b : listBook) {
+            if (b.compareTitle(title)) {
+                targetBook = b;
+                break;
+            }
+        }
+
+        if (targetBook == null) {
+            throw new NotItemException("Book not found.");
+        }
+
+        // Add or replace a review
+        targetBook.addOrUpdateReview(login.trim(), mark, comment);
+
+        // Returns the new average mark
+        return targetBook.getAverageMark();
     }
 
     @Override
diff --git a/src/tests/ReviewItemBookTest.java b/src/tests/ReviewItemBookTest.java
new file mode 100644
index 0000000..109a75e
--- /dev/null
+++ b/src/tests/ReviewItemBookTest.java
@@ -0,0 +1,90 @@
+package tests;
+
+import opinion.SocialNetwork;
+import opinion.ISocialNetwork;
+import exceptions.*;
+
+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++;
+        try {
+            float result = sn.reviewItemBook(login, password, title, mark, comment);
+            if (Math.abs(result - expectedAverage) < 0.01f) {
+                displaySuccess("[" + testId + "] Average = " + result);
+            } else {
+                displayError("[" + testId + "] Expected " + expectedAverage + " but got " + result);
+            }
+        } catch (Exception e) {
+            displayError("[" + testId + "] Unexpected exception: " + e);
+        }
+    }
+
+    private static void testExpectedException(ISocialNetwork sn, String login, String password, String title,
+                                              float mark, String comment, Class<?> expectedException, String testId) {
+        nbTests++;
+        try {
+            sn.reviewItemBook(login, password, title, mark, comment);
+            displayError("[" + testId + "] Expected exception " + expectedException.getSimpleName() + " but none was thrown");
+        } catch (Exception e) {
+            if (e.getClass().equals(expectedException)) {
+                displaySuccess("[" + testId + "] Correctly threw " + expectedException.getSimpleName());
+            } else {
+                displayError("[" + testId + "] Unexpected exception: " + e);
+            }
+        }
+    }
+
+    public static TestReport test() {
+        ISocialNetwork sn = new SocialNetwork();
+
+        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);
+        } catch (Exception e) {
+            System.out.println("Setup failed: " + e.getMessage());
+            return null;
+        }
+
+        // --- Casos exitosos ---
+        testExpectedAverage(sn, "ana", "pass123", "El Hobbit", 4.0f, "Muy bueno", 4.0f, "1.1");
+        testExpectedAverage(sn, "luis", "1234pass", "El Hobbit", 5.0f, "Obra maestra", 4.5f, "1.2");
+        testExpectedAverage(sn, "ana", "pass123", "El Hobbit", 3.0f, "Bueno pero largo", 4.0f, "1.3");
+
+        // --- Casos de error esperados ---
+        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");
+
+        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();
+    }
+}
-- 
GitLab