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