From 837cf93c5eec1f6c7ae866e6c708e7c388e8168e Mon Sep 17 00:00:00 2001 From: Fredrik Marjoni Date: Thu, 26 Feb 2026 11:03:46 +0100 Subject: [PATCH 1/6] feat[User]: add constructor and get methods --- .../java/edu/group5/app/model/user/User.java | 111 +++++++++++++++++- .../edu/group5/app/model/user/User.class | Bin 289 -> 1917 bytes 2 files changed, 110 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/group5/app/model/user/User.java b/src/main/java/edu/group5/app/model/user/User.java index e163785..939bea9 100644 --- a/src/main/java/edu/group5/app/model/user/User.java +++ b/src/main/java/edu/group5/app/model/user/User.java @@ -1,5 +1,114 @@ package edu.group5.app.model.user; +/** + * User class represents a user in the system. It is an abstract class that will be extended by specific user types such as Donor, Recipient, and Admin. + * Each user has a unique userId, a role that defines their permissions in the system, and personal information such as first name, last name, email, and password hash. + * The constructor validates that all required fields are provided and throws an IllegalArgumentException if any of the fields are null or empty. + * This ensures that the User objects are always in a valid state when created. + */ +public abstract class User { + private int userId; + private String role; + private String firstName; + private String lastName; + private String email; + private String passwordHash; + + /** + * Constructor for User class. Validates that all required fields + * are provided and throws an IllegalArgumentException if any of the fields are null or empty. + * @param userId the unique identifier for the user, must be a positive integer + * @param role the role of the user (e.g., "Donor", "Recipient", "Admin") + * @param firstName the first name of the user + * @param lastName the last name of the user + * @param email the email address of the user + * @param passwordHash the hashed password of the user + */ + public User(int userId, String role, String firstName, + String lastName, String email, String passwordHash) { + if (userId <= 0) { + throw new IllegalArgumentException("User ID must be positive"); + } + if (role == null || role.trim().isEmpty()) { + throw new IllegalArgumentException("Role cannot be null or empty"); + } + if (firstName == null || firstName.trim().isEmpty()) { + throw new IllegalArgumentException("First name cannot be null or empty"); + } + if (lastName == null || lastName.trim().isEmpty()) { + throw new IllegalArgumentException("Last name cannot be null or empty"); + } + if (email == null || email.trim().isEmpty()) { + throw new IllegalArgumentException("Email cannot be null or empty"); + } + if (passwordHash == null || passwordHash.trim().isEmpty()) { + throw new IllegalArgumentException("Password hash cannot be null or empty"); + } + this.userId = userId; + this.role = role.trim(); + this.firstName = firstName.trim(); + this.lastName = lastName.trim(); + this.email = email.trim(); + this.passwordHash = passwordHash; +} -public class User { + /** + * Gets the unique identifier for the user. + * @return the userId of the user + */ + public int getUserId() { + return userId; + } + + /** + * Gets the role of the user, which defines their permissions in the system. + * @return the role of the user + */ + public String getRole() { + return role; + } + + /** + * Gets the first name of the user. + * @return the first name of the user + */ + public String getFirstName() { + return firstName; + } + /** + * Gets the last name of the user. + * @return the last name of the user + */ + public String getLastName() { + return lastName; + } + + /** + * Gets the email address of the user. + * @return the email of the user + */ + public String getEmail() { + return email; + } + + /** + * Gets the hashed password of the user. + * This is used for authentication purposes and should not be exposed in plaintext. + * @return the password hash of the user + */ + public String getPasswordHash() { + return passwordHash; + } + + /** + * Verifies if the provided password matches the stored password hash for the user. + * This method should implement the logic to hash the input password + * and compare it with the stored password hash. + * @param password the plaintext password to verify + * @return true if the password is correct, false otherwise + */ + public boolean verifyPassword(String password) { + // TODO Implement password verification logic here, e.g., using a hashing algorithm + return true; // Placeholder return value + } } diff --git a/target/classes/edu/group5/app/model/user/User.class b/target/classes/edu/group5/app/model/user/User.class index 950b2f7160ec2652685a7081f89e90b9a1c868d5..4f41b157efad2b627e7442266011a3ad90367176 100644 GIT binary patch literal 1917 zcmb_cL37hq5dNNHTXrHR5CSD60R>2EizEsmgtVcw5F9WB+97RbN;{oVY~hH?l17qK z_yaxn(nDv;vA0gAovF!8JA@kteiX3#Venv&l{%i8x5~!IYu+I0^=K66r=?X+&8yO!!g~u@#V&Ss~QPp*`rbu5EX%R z;5nAS;OZN{wJ5ON`jSBYo*jhIZL>iRImg@;Ggia29Rbxh!|*3Bs9iV1O$vL_cJ1hr zzz@aB-e@06Q(C8-m#NTR^x&Y10tN+oiluc0Ljot?R8espt8O}%gL<=Jxl#E+)$$|T zb8|Q%aFqGcDp$2eGmNwiOY^af7!;@+f7>%ADkn1ay`YGcY&9LEVt zkN9f{3>8az@r)id<^oa@;Ie~#y+qG^t8yi;ewYd=wq*pbabu+N}+*YQeO*<6OR^L7N zG`fYg$gKW&%ka zzhwpXy@$KXeMaUky`J5tBG9|$HG`_PV)NB`&S{2+Ha$*c_0Z$aBE>9{lwuC$P7KPO z_>()aCwJnG_8cJ#=%;l65WiCtg|s{RHV%wDLg9ZL`gZW}Ha>bf^$dln$2j&F+HYteWZmMo$qg9R_FU#nA2tW z7Up#st%U`BINQSFKU6^vKBe^zhG;#8G)Ae?F%04aH2QRUM2k3uE0`dkNqmnY9F(wy zGx!-(_ysfg6$Tz*7JuL@{=yu#aSl%~k0pwDJ!T0P@fn?nFUh))67!yt5;MG-bYKj6O6pXz60}A;RQnQnB(}buhZIc+zbt`@WcS7^xkGsQ delta 159 zcmey%w~&eJ)W2Q(7#J8_83ZPB*~;2v=4F=HF)}b~XofK|usG+Zq;fGZGjQ@Surjbs zzRnb!#TA@iT9lmXmYI{v$iNv|oLZ!pl~|U@pvVB!1vH2ONHc;|14(uuPan)@U|`kS m&cLw|D8R(P1tdYz3_uOsK#~W{W(Cr`KprClACP2X;0FLGfEL^U From b9693b75fd3928334c1dc67372f69c4ba2e5224b Mon Sep 17 00:00:00 2001 From: Fredrik Marjoni Date: Thu, 26 Feb 2026 11:57:03 +0100 Subject: [PATCH 2/6] feat[User]: Add Bcrpyt in verifying password in class and dependency in pom.xml --- pom.xml | 7 +++++++ .../java/edu/group5/app/model/user/User.java | 18 ++++++++++++------ .../edu/group5/app/model/user/User.class | Bin 1917 -> 2200 bytes 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 4895163..4d088c4 100644 --- a/pom.xml +++ b/pom.xml @@ -32,6 +32,13 @@ javafx-controls ${javafx.version} + + + + org.springframework.security + spring-security-crypto + 7.0.2 + diff --git a/src/main/java/edu/group5/app/model/user/User.java b/src/main/java/edu/group5/app/model/user/User.java index 939bea9..e20e4f4 100644 --- a/src/main/java/edu/group5/app/model/user/User.java +++ b/src/main/java/edu/group5/app/model/user/User.java @@ -1,9 +1,13 @@ package edu.group5.app.model.user; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; /** * User class represents a user in the system. It is an abstract class that will be extended by specific user types such as Donor, Recipient, and Admin. * Each user has a unique userId, a role that defines their permissions in the system, and personal information such as first name, last name, email, and password hash. * The constructor validates that all required fields are provided and throws an IllegalArgumentException if any of the fields are null or empty. * This ensures that the User objects are always in a valid state when created. + * The class also includes a method to verify the user's password + * by comparing the provided plaintext password with the stored hashed password using BCrypt. + * */ public abstract class User { private int userId; @@ -21,7 +25,7 @@ public abstract class User { * @param firstName the first name of the user * @param lastName the last name of the user * @param email the email address of the user - * @param passwordHash the hashed password of the user + * @param passwordHash the hashed password of the user, used for authentication purposes */ public User(int userId, String role, String firstName, String lastName, String email, String passwordHash) { @@ -101,14 +105,16 @@ public String getPasswordHash() { } /** - * Verifies if the provided password matches the stored password hash for the user. - * This method should implement the logic to hash the input password - * and compare it with the stored password hash. + * Verifies if the provided password matches the stored password hash. + * This method uses BCrypt to compare the plaintext password with the hashed password. * @param password the plaintext password to verify * @return true if the password is correct, false otherwise */ public boolean verifyPassword(String password) { - // TODO Implement password verification logic here, e.g., using a hashing algorithm - return true; // Placeholder return value + if (password == null || password.isEmpty()) { + return false; + } + BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); + return encoder.matches(password, this.passwordHash); } } diff --git a/target/classes/edu/group5/app/model/user/User.class b/target/classes/edu/group5/app/model/user/User.class index 4f41b157efad2b627e7442266011a3ad90367176..a863d4f6ccfa7c6a4b044c45dcae7ab0efd15832 100644 GIT binary patch delta 509 zcmbu5O-mb56o#McsL}BY1-BZpXlo)Peg>mfA{tv0zo8Ta8OJg4E73cNB3-!ax+N6a zMR&SWL0V$5)I}Fv_$&MqE|s2%KS3^>`@HWx=Wxz_sQ=n%-acO60Fx|Vn&-xGfH#Wq ztWH_pp5Dx)HnhF#9%l8n<+)B?Z|06HM<4CwvesJZwqg^$oVPtsveqXvPIleZCet+f zAyG?`Sw&#i&N*qT)pF7$#fI*8Coj8`m*S|Q91-5g-?ksdzL%NP3iPCus%aKRu~ z4Dp9ZAzpE!UKj2vn+vM4Q^iX(CNx)~4?^!s^h;<}XhfxbeLO`RMT7jfham@AL;o;C zMS|a`FwTB6{r-x#$#AIaCy^pEXOdztEU`%z08NdQ){&=K291gnd}_l8qoSlCbF!wA WcawP*C}T|Aa>{BH)k-!+tfl`Z*MLF* delta 240 zcmbOs_?M6C)W2Q(7#J8_8N4@gt!3tBWZ)=BEG{n3FG|_GfW?B*SBim!L56{YL6$*? zL7qVY2(=iL7%Ui+8JrkY8G;zp7-ASS7;+di8Oj*68QK_h7$z|2F-&F9XPC=iz_66T zkYOEz5yN%{V}`v9CX-d!mM~gRZe$moe4kC7(HYE=VOMAL2D2i8tY9F^hA|q Date: Thu, 26 Feb 2026 12:44:50 +0100 Subject: [PATCH 3/6] feat[test]: add tests classes to visually display the folder structure of the project --- src/test/java/edu/group5/app/control/WrapperTest.java | 5 +++++ .../java/edu/group5/app/model/donation/DonationTest.java | 5 +++++ .../edu/group5/app/model/organization/OrganizationTest.java | 5 +++++ src/test/java/edu/group5/app/model/user/UserTest.java | 5 +++++ src/test/java/edu/group5/app/utils/UtilitiesTest.java | 5 +++++ src/test/java/edu/group5/app/view/ViewTest.java | 5 +++++ 6 files changed, 30 insertions(+) create mode 100644 src/test/java/edu/group5/app/control/WrapperTest.java create mode 100644 src/test/java/edu/group5/app/model/donation/DonationTest.java create mode 100644 src/test/java/edu/group5/app/model/organization/OrganizationTest.java create mode 100644 src/test/java/edu/group5/app/model/user/UserTest.java create mode 100644 src/test/java/edu/group5/app/utils/UtilitiesTest.java create mode 100644 src/test/java/edu/group5/app/view/ViewTest.java diff --git a/src/test/java/edu/group5/app/control/WrapperTest.java b/src/test/java/edu/group5/app/control/WrapperTest.java new file mode 100644 index 0000000..d626fd7 --- /dev/null +++ b/src/test/java/edu/group5/app/control/WrapperTest.java @@ -0,0 +1,5 @@ +package edu.group5.app.control; + +public class WrapperTest { + +} diff --git a/src/test/java/edu/group5/app/model/donation/DonationTest.java b/src/test/java/edu/group5/app/model/donation/DonationTest.java new file mode 100644 index 0000000..a905209 --- /dev/null +++ b/src/test/java/edu/group5/app/model/donation/DonationTest.java @@ -0,0 +1,5 @@ +package edu.group5.app.model.donation; + +public class DonationTest { + +} diff --git a/src/test/java/edu/group5/app/model/organization/OrganizationTest.java b/src/test/java/edu/group5/app/model/organization/OrganizationTest.java new file mode 100644 index 0000000..45e04ca --- /dev/null +++ b/src/test/java/edu/group5/app/model/organization/OrganizationTest.java @@ -0,0 +1,5 @@ +package edu.group5.app.model.organization; + +public class OrganizationTest { + +} diff --git a/src/test/java/edu/group5/app/model/user/UserTest.java b/src/test/java/edu/group5/app/model/user/UserTest.java new file mode 100644 index 0000000..bc0bcce --- /dev/null +++ b/src/test/java/edu/group5/app/model/user/UserTest.java @@ -0,0 +1,5 @@ +package edu.group5.app.model.user; + +public class UserTest { + +} diff --git a/src/test/java/edu/group5/app/utils/UtilitiesTest.java b/src/test/java/edu/group5/app/utils/UtilitiesTest.java new file mode 100644 index 0000000..88aa0c9 --- /dev/null +++ b/src/test/java/edu/group5/app/utils/UtilitiesTest.java @@ -0,0 +1,5 @@ +package edu.group5.app.utils; + +public class UtilitiesTest { + +} diff --git a/src/test/java/edu/group5/app/view/ViewTest.java b/src/test/java/edu/group5/app/view/ViewTest.java new file mode 100644 index 0000000..bd0cd83 --- /dev/null +++ b/src/test/java/edu/group5/app/view/ViewTest.java @@ -0,0 +1,5 @@ +package edu.group5.app.view; + +public class ViewTest { + +} From fae604f512c477b0117e9155c18647d3d0ed24a8 Mon Sep 17 00:00:00 2001 From: Fredrik Marjoni Date: Thu, 26 Feb 2026 12:50:56 +0100 Subject: [PATCH 4/6] update: delete target by mvn clean --- target/classes/edu/group5/app/App.class | Bin 543 -> 0 bytes .../classes/edu/group5/app/control/Wrapper.class | Bin 292 -> 0 bytes .../edu/group5/app/model/donation/Donation.class | Bin 309 -> 0 bytes .../app/model/organization/Organization.class | Bin 329 -> 0 bytes .../classes/edu/group5/app/model/user/User.class | Bin 2200 -> 0 bytes .../classes/edu/group5/app/utils/Utilities.class | Bin 294 -> 0 bytes target/classes/edu/group5/app/view/View.class | Bin 277 -> 0 bytes .../compile/default-compile/createdFiles.lst | 1 - .../compile/default-compile/inputFiles.lst | 1 - target/test-classes/edu/group5/app/AppTest.class | Bin 503 -> 0 bytes 10 files changed, 2 deletions(-) delete mode 100644 target/classes/edu/group5/app/App.class delete mode 100644 target/classes/edu/group5/app/control/Wrapper.class delete mode 100644 target/classes/edu/group5/app/model/donation/Donation.class delete mode 100644 target/classes/edu/group5/app/model/organization/Organization.class delete mode 100644 target/classes/edu/group5/app/model/user/User.class delete mode 100644 target/classes/edu/group5/app/utils/Utilities.class delete mode 100644 target/classes/edu/group5/app/view/View.class delete mode 100644 target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst delete mode 100644 target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst delete mode 100644 target/test-classes/edu/group5/app/AppTest.class diff --git a/target/classes/edu/group5/app/App.class b/target/classes/edu/group5/app/App.class deleted file mode 100644 index e3679e1b8be800f5bef6f802b19397fadbe36584..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 543 zcmZuu%SyvQ6g|^d9!6XH@~y3_)`eM#i;5tkxCkm#>cZ8u9paQE6VgQRvvi^0!VmDH z#G6*A#S%Do?!9x)J#+K*{qYIl0{a>=3}rD)Y&TL#cx3Z1w9mp&Lyn;|;!oW6c;MPM z{gD{N422UJ$oP~Y+iLe1a_4F&Ok`nL$fLkebYvi|6TdH_JKpyMi92e*y&jKbn*SDa z@uM6wRGt5mJEZD!88Fma56;X%H;!cBcG^7ytEgxw&-v>&RR63emm)S(Z+Lm_;K zxyx^Vwru~tTz~%nEYT0)5e8~si-R?FITNxhMP`c1nq2HGld>UvLjNScq{wA)5bN}$ zvWn1r)rGF!2#xV%OYj$FuOc+ijuD_q=q0*P@AYS@?1xNqMR-n3CiAVd+VP|4S4Vv& z43qy|%n8xP)HYKq?RLcvcQ4KuMqnHK5;&4O&l)m`I|IS=2d!@|c!*eC8$8fqjqiED M@rjAhW%baz0k+0J=l}o! diff --git a/target/classes/edu/group5/app/model/donation/Donation.class b/target/classes/edu/group5/app/model/donation/Donation.class deleted file mode 100644 index 687d00e7e82e816b337c9de3a13b0be79dc8c689..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 309 zcma)%F>b;@5JmqO8-oJ@aRV9z6xk|OqBJC_EGR(qYkLKY%&ui@?nM=eA_vH!B4!cv zG=Jv*(Tv{w{hxmUe4!u0BaBp5i%n_k;#J6^5PO@cTx8bBN?Rj7Z%qiF(BH|U6uC4T zu}F3*tq9F`ZFKcPXpARofu|D>)9hH7#OlW2g(ud| OwGX&<*%6*uJ@hV=jz&NL diff --git a/target/classes/edu/group5/app/model/organization/Organization.class b/target/classes/edu/group5/app/model/organization/Organization.class deleted file mode 100644 index af118ddfe1be2c754d3f950677451cf175401840..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 329 zcmb7pP5!g$MX ztZKHES{7SfwuJt@v8H_>^rly9LOho<8G1M!AVHrn%8k`e-LBC7nTuKzE^}9My=HF$ z{}1E##k>-3^5d-T2-(VYzSNH<+`c$eo&{S>Aa3$+NTuK;nF^^r1IhI#PCjH1A(ITx TkcBhJ!M;zVo(mC%k`YFK{nk$L diff --git a/target/classes/edu/group5/app/model/user/User.class b/target/classes/edu/group5/app/model/user/User.class deleted file mode 100644 index a863d4f6ccfa7c6a4b044c45dcae7ab0efd15832..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2200 zcmb_dT~ixX7=BJjvPsxLOF@gYu=InHKv<+eQEES+p+o~zs5oUDoz1c&+irH({XqEx zUVGz(GxpNEj-xXMX6%S}T==8Z_nZy3fuI*U$?SR0d(QLjd!FYx$?t#satNS^#}Z-; zgT{8KRy`+lXH?B~)w;87SZe4Sp863zB*YocJ=JzK)za*$x>k8==mA5L?R*gi+T_i$QiZ-~Yn#wwE=(MrCiCwi(=E z_;j>%y4wGh$!${4i*(QoI&fY_7Cj6dqq$89y$n}gouXt}Mpd)!d)2UR*g^42-Eafb zu~T@1;UecpDLqi?p&uv}LvbD749s1sdI1-C)qaM)(bG-mHZvH&WeJyBsEsI-F^C~* zkNB%I^p56E<2ia*#uZ#;kW9Z=cY{6A|5ggu87{4p8j7yjwjZlN(F}NkD4+oHPZR4t!Xf*G7?Dg=xrGiQarjT zBOOIEGBQzgOGalDy(2?LilMt~+Qw>FuNdBAtr8j1(KTyR^GrT(CgVZP^cj@$KO3K{ zo81UB{n?7}MLs<)TeNlZ zyO+T-&htlE#tK&H1a&RYYX%Wgc-^UsHO<>FJ`W9BH|9?}FtZ^wX6@jC+Kl7D6O6+`0lQG~6(;dDrtl4J z;yI@AJ!bF&W^sU9_?1xeRB<_C3Agbc&4@3-IujA+JtiW~JXhtA-%RR(N1XkHh&caA z+@W{`oqtkmk_5&i47~mYvgvHPTYN~PySNuAMSapA3}F-bpE2=*f|xjPQY7z+Cgo^D zvq^^g7@`cx+yb8b@dWr`Tkt|#@YG50T3hg9Tk!Nr@W*Yz588rfPl7*d3of<=&z%I< z+Jcwxut}ItI&vk4#*UB~6IUS7@!}n9|(W*}&TQ+TskT6{9Z>F(|qWxFoc`5%5|~O4g35%4DA=U zguC>Ai)TVIuUwOxH}Y4I_w%dYRb-afgeo3<4xV{|s5U6!y=3 NB=t&?oE8QcoB)e9K-&NS diff --git a/target/classes/edu/group5/app/view/View.class b/target/classes/edu/group5/app/view/View.class deleted file mode 100644 index bc21f75c019877955f50631d6137819bf7288900..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 277 zcmZ{fJ&wXa427RVLLmH#3enL41ygOcXdA><5fq^GlQ4ooA&IgHoQrBD3J$=bR(PUq zX+HbevY-9@yFUP|(05@GhH77mL!Oq|hmct&E?Qkhz;Iy``X_mjB9_TPY{HX@3POFM z6J2}}YLjU|u$Spxd8nb;hJ!kx=j%kR%X6smoeX0|82D)<<3Q%x=>MW!9Q6-j)!&6cJ)YHseq80^kJfFl`KrproH8gOR6XxzA9!DE^>c%a2>SGmKn!-~*l HTIjt1jj%a; diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst deleted file mode 100644 index 28e9804..0000000 --- a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +++ /dev/null @@ -1 +0,0 @@ -edu\group5\app\App.class diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst deleted file mode 100644 index 16a5464..0000000 --- a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +++ /dev/null @@ -1 +0,0 @@ -C:\Users\marjo\Documents\Github\Help-Me-Help\src\main\java\edu\group5\app\App.java diff --git a/target/test-classes/edu/group5/app/AppTest.class b/target/test-classes/edu/group5/app/AppTest.class deleted file mode 100644 index 4c6649954e613037560eadfde5c4dcaf50c01019..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 503 zcmZutO-sW-6r4@dMq{)e*4lyxy;Tq9Af75h5IqG2Efu_N+oj!-?uN}qf0rl4gFnC@ zCBCEuFTK3k_vSHgXMTRaz5(2#=fPp_S@i3n zYv(d!=*F9`4;b3nT<6I&QrVj@&(h9^CMUJtW3H@RijmAD$wf+O%dOOk)Q)0pX5k{I z4^mB~6^1Oyu<$eR(L&q9KEv_mttiWcDU|{opu^zva&m$Xl{paCB{RD;z5;VyLyd&D}ZueTb6h0p~t YrI7oH=D(0nt3VSj8QdgxNUVeIAF#x0fB*mh From 8bd6986511498780071f5d99c0223bde9a634d99 Mon Sep 17 00:00:00 2001 From: Fredrik Marjoni Date: Thu, 26 Feb 2026 13:23:59 +0100 Subject: [PATCH 5/6] test[User]: Add dependency for the Bcrypt, and add positive and Negative JUnit tests --- pom.xml | 5 + .../java/edu/group5/app/model/user/User.java | 2 +- .../edu/group5/app/model/user/UserTest.java | 108 +++++++++++++++++- 3 files changed, 113 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index b0f6764..5f7773d 100644 --- a/pom.xml +++ b/pom.xml @@ -38,6 +38,11 @@ spring-security-crypto 7.0.2 + + commons-logging + commons-logging + 1.3.5 + diff --git a/src/main/java/edu/group5/app/model/user/User.java b/src/main/java/edu/group5/app/model/user/User.java index e20e4f4..8dd48cd 100644 --- a/src/main/java/edu/group5/app/model/user/User.java +++ b/src/main/java/edu/group5/app/model/user/User.java @@ -9,7 +9,7 @@ * by comparing the provided plaintext password with the stored hashed password using BCrypt. * */ -public abstract class User { +public class User { private int userId; private String role; private String firstName; diff --git a/src/test/java/edu/group5/app/model/user/UserTest.java b/src/test/java/edu/group5/app/model/user/UserTest.java index bc0bcce..b49f153 100644 --- a/src/test/java/edu/group5/app/model/user/UserTest.java +++ b/src/test/java/edu/group5/app/model/user/UserTest.java @@ -1,5 +1,111 @@ package edu.group5.app.model.user; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + public class UserTest { - + private static final int TEST_USER_ID = 1; + private static final String TEST_ROLE = "Donor"; + private static final String TEST_FIRST_NAME = "John"; + private static final String TEST_LAST_NAME = "Doe"; + private static final String TEST_EMAIL = "john.doe@example.com"; + private static final String TEST_PASSWORD = "password123"; + private static final String TEST_PASSWORD_HASH = new BCryptPasswordEncoder().encode(TEST_PASSWORD); + + private static final int WRONG_USER_ID = -5; + private static final String WRONG_ROLE = ""; + private static final String WRONG_FIRST_NAME = ""; + private static final String WRONG_LAST_NAME = ""; + private static final String WRONG_EMAIL = ""; + private static final String WRONG_PASSWORD_HASH = ""; + + private void constructorTest(int userId, String role, String firstName, String lastName, String email, String passwordHash, boolean negativeTest) { + boolean exceptionThrown = negativeTest; + try { + new User(userId, role, firstName, lastName, email, passwordHash); + } catch (Exception e) { + exceptionThrown = !negativeTest; + } finally { + assertFalse(exceptionThrown); + } + } + + @Test + public void constructorThrowsNoException() { + constructorTest(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH, false); + } + + @Test + public void constructorWithNegativeUserIdThrowsException() { + constructorTest(WRONG_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH, true); + } + + @Test + public void constructorWithEmptyRoleThrowsException() { + constructorTest(TEST_USER_ID, WRONG_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH, true); + } + + @Test + public void constructorWithEmptyFirstNameThrowsException() { + constructorTest(TEST_USER_ID, TEST_ROLE, WRONG_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH, true); + } + + @Test + public void constructorWithEmptyLastNameThrowsException() { + constructorTest(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, WRONG_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH, true); + } + + @Test + public void constructorWithEmptyEmailThrowsException() { + constructorTest(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, WRONG_EMAIL, TEST_PASSWORD_HASH, true); + } + + @Test + public void constructorWithEmptyPasswordHashThrowsException() { + constructorTest(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, WRONG_PASSWORD_HASH, true); + } + + private void getMethodComparer(User user, boolean negativeTest) { + if (user.getUserId() == TEST_USER_ID && + user.getRole().equals(TEST_ROLE) && + user.getFirstName().equals(TEST_FIRST_NAME) && + user.getLastName().equals(TEST_LAST_NAME) && + user.getEmail().equals(TEST_EMAIL) && + user.getPasswordHash() != null) { + assertFalse(negativeTest); + } + } + + @Test + public void getMethodsReturnCorrectInformation() { + User testUser = new User(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH); + getMethodComparer(testUser, false); + } + + @Test + public void verifyPasswordReturnsTrueForCorrectPassword() { + User testUser = new User(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH); + assertTrue(testUser.verifyPassword(TEST_PASSWORD)); + } + + @Test + public void verifyPasswordReturnsFalseForIncorrectPassword() { + User testUser = new User(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH); + assertFalse(testUser.verifyPassword("wrongPassword")); + } + + @Test + public void verifyPasswordReturnsFalseForNullPassword() { + User testUser = new User(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH); + assertFalse(testUser.verifyPassword(null)); + } + + @Test + public void verifyPasswordReturnsFalseForEmptyPassword() { + User testUser = new User(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH); + assertFalse(testUser.verifyPassword("")); + } } From 50b7c3aefbf8fa75fa28bfd732129387ec5d377d Mon Sep 17 00:00:00 2001 From: Fredrik Marjoni Date: Thu, 26 Feb 2026 13:38:18 +0100 Subject: [PATCH 6/6] update[User]: Add negative test scenario for null-inputs for better coverage --- .../edu/group5/app/model/user/UserTest.java | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/test/java/edu/group5/app/model/user/UserTest.java b/src/test/java/edu/group5/app/model/user/UserTest.java index b49f153..1e7277a 100644 --- a/src/test/java/edu/group5/app/model/user/UserTest.java +++ b/src/test/java/edu/group5/app/model/user/UserTest.java @@ -95,17 +95,42 @@ public void verifyPasswordReturnsTrueForCorrectPassword() { public void verifyPasswordReturnsFalseForIncorrectPassword() { User testUser = new User(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH); assertFalse(testUser.verifyPassword("wrongPassword")); - } + } @Test public void verifyPasswordReturnsFalseForNullPassword() { User testUser = new User(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH); assertFalse(testUser.verifyPassword(null)); - } + } @Test public void verifyPasswordReturnsFalseForEmptyPassword() { User testUser = new User(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH); assertFalse(testUser.verifyPassword("")); - } + } + + @Test + public void constructorWithNullRoleThrowsException() { + constructorTest(TEST_USER_ID, null, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH, true); + } + + @Test + public void constructorWithNullFirstNameThrowsException() { + constructorTest(TEST_USER_ID, TEST_ROLE, null, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH, true); + } + + @Test + public void constructorWithNullLastNameThrowsException() { + constructorTest(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, null, TEST_EMAIL, TEST_PASSWORD_HASH, true); + } + + @Test + public void constructorWithNullEmailThrowsException() { + constructorTest(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, null, TEST_PASSWORD_HASH, true); + } + + @Test + public void constructorWithNullPasswordHashThrowsException() { + constructorTest(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, null, true); + } }