Skip to content

Commit

Permalink
Merge pull request #79 from Group-5/test/wrapper
Browse files Browse the repository at this point in the history
Test/wrapper
  • Loading branch information
fredrjm authored Apr 22, 2026
2 parents 9f9fb18 + f22ad07 commit 380d1c6
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 30 deletions.
108 changes: 90 additions & 18 deletions src/main/java/edu/group5/app/control/AuthController.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**
Expand Down Expand Up @@ -74,44 +78,112 @@ public User getCurrentUser() {
* @param passwordChars the user's password
*/
public void handleSignUp(SignUpPageView view, String firstName, String lastName, String email, char[] passwordChars) {
if (firstName == null || firstName.trim().isEmpty() ||
lastName == null || lastName.trim().isEmpty() ||
email == null || email.trim().isEmpty() ||
passwordChars == null || passwordChars.length == 0) {
if (firstName == null || firstName.trim().isEmpty()
|| lastName == null || lastName.trim().isEmpty()
|| email == null || email.trim().isEmpty()
|| passwordChars == null || passwordChars.length == 0) {
view.showError("All fields are required");
return;
}

BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

// Clears password char array after creating a hash.
String hashedPassword = encoder.encode(new String(passwordChars));
for (int i = 0; i < passwordChars.length; i++) {
passwordChars[i] = '\u0000';
// Checks if any input is too long.
if (firstName.length() > 32 || lastName.length() > 32
|| email.length() > 32 || passwordChars.length > 72) {

HashMap<String, List<String>> fields = new HashMap<String, List<String>>();
List<String> fields32 = new ArrayList<String>();
List<String> fields72 = new ArrayList<String>();
fields.put("32", fields32);
fields.put("72", fields72);

if (firstName.length() > 32) {
fields32.add("First Name");
}
if (lastName.length() > 32) {
fields32.add("Last Name");
}
if (email.length() > 32) {
fields32.add("Email");
}
if (passwordChars.length > 72) {
fields72.add("Password");
}

int length32 = fields.get("32").size();
int length72 = fields.get("72").size();

String string32 = "";
if (length32 > 0) {
if (length32 > 1) {
for (int i = 0; i < length32; i++) {
if (i == length32 - 1) {
string32 += String.format("and %s", fields.get("32").get(i));
} else {
string32 += String.format("%s, ", fields.get("32").get(i));
}
}
string32 = string32 + " must have lengths of 32 characters.\n";
} else {
string32 = fields.get("32").getFirst() + " must have a length of 32 characters.\n";
}
}

String string72 = "";
if (length72 > 0) {
if (length72 > 1) {
for (int i = 0; i < length72; i++) {
if (i == length72 - 1) {
string72 += String.format("and %s", fields.get("72").get(i));
} else {
string72 += String.format("%s, ", fields.get("72").get(i));
}
}
string72 = string72 + " must have lengths of 72 characters.\n";
} else {
string72 = fields.get("72").getFirst()
+ " must have a length of 72 characters.\n";
}
}

view.showError(string32 + string72 + "Try again.");
return;
}

// Privacy policy pop-up.
Alert privacyPolicy = new Alert(Alert.AlertType.CONFIRMATION);
privacyPolicy.setTitle("Accept Privacy Policy");
privacyPolicy.setHeaderText("Accept Privacy Policy");
privacyPolicy.setContentText(
"Your user information like:\n" +
"Name and email—as well as donations tied to your account—will be saved locally on your machine.\n" +
"This information is only used to create your account, and no data will be sold to third parties.\n" +
"By creating an account, you accept the right of our app to store this information on your computer.");
"Your user information like:\n"
+ "Name and email—as well as donations tied to your account—"
+ "will be saved locally on your machine.\n"
+ "This information is only used to create your account,"
+ "and no data will be sold to third parties.\n"
+ "By creating an account,"
+ "you accept the right of our app to store this information on your computer.");

BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
// Clears password char array after creating a hash.
String hashedPassword = encoder.encode(new String(passwordChars));
for (int i = 0; i < passwordChars.length; i++) {
passwordChars[i] = '\u0000';
}

if (privacyPolicy.showAndWait().orElse(ButtonType.CANCEL) == ButtonType.OK) {
boolean success = userService.registerUser(
"Customer", firstName, lastName, email, hashedPassword);

if (success) {

User user = userService.getUserByEmail(email);
appState.setCurrentUser(user);
nav.showHomePage();
} else {
view.showError("Registration failed. Email may already be in use.");
nav.showHomePage();
} else {
view.showError("Registration failed. Email may already be in use.");
}
}
}
}


/**
* Handles the login of a {@link User}.
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/edu/group5/app/control/DonationController.java
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,12 @@ private void handleDonate() {
return;
}

// Prevents donations that are too complex from being made
if (amount.stripTrailingZeros().precision() > 32 || amount.stripTrailingZeros().scale() > 16) {
this.showError("The number is too complex, please donate a smaller or less precise number");
return;
}

// Create donation via service
boolean success = service.donate(
customer,
Expand Down
10 changes: 8 additions & 2 deletions src/main/java/edu/group5/app/model/wrapper/DbWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,10 @@ public List<Object[]> importUsers() {
* @throws IllegalArgumentException This exception is thrown when data is null, its rows are not
* of length 6, any of the rows are null, any of the rows are duplicates or existing rows in
* the database, or any of the values in the rows can't be cast to the correct data-types.
* @throws SQLException Is thrown when an unexpected exception like trying to export a number
* that's too big happens.
*/
public int exportUsers(List<Object[]> data) throws IllegalArgumentException {
public int exportUsers(List<Object[]> data) throws IllegalArgumentException, SQLException {
this.importUsers();

ParameterValidator.exportChecker(data, "data", this.users, 6);
Expand Down Expand Up @@ -163,6 +165,7 @@ public int exportUsers(List<Object[]> data) throws IllegalArgumentException {
this.logger.info("Users exported");
} catch (SQLException e) {
this.logger.log(Level.SEVERE, "Unexpected SQL exception", e);
throw new SQLException("An unexpected SQL exception has occurred. This might be caused by inserting an item that is too large.");
} finally {
this.close(null, ps);
}
Expand Down Expand Up @@ -230,8 +233,10 @@ private List<Object[]> importDonations(int user_id, boolean all) {
* @throws IllegalArgumentException This exception is thrown when data is null, its rows are not
* of length 6, any of the rows are null, any of the rows are duplicates or existing rows in
* the database, or any of the values in the rows can't be cast to the correct data-types.
* @throws SQLException Is thrown when an unexpected exception like trying to export a number that's
* too big happens.
*/
public int exportDonations(List<Object[]> data) throws IllegalArgumentException {
public int exportDonations(List<Object[]> data) throws IllegalArgumentException, SQLException {
this.fetchAllDonations();

ParameterValidator.exportChecker(data, "data", this.donations, 6);
Expand Down Expand Up @@ -263,6 +268,7 @@ public int exportDonations(List<Object[]> data) throws IllegalArgumentException
this.logger.info("Donations exported");
} catch (SQLException e) {
this.logger.log(Level.SEVERE, "Unexpected SQL exception", e);
throw new SQLException("An unexpected SQL exception has occurred. This might be caused by inserting an item that is too large.");
} finally {
this.close(null, ps);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public char[] getPassword() {

public void showError(String message) {
errorLabel.setText(message);
errorLabel.setWrapText(true);
errorLabel.setStyle("-fx-text-fill: red;");
}

Expand All @@ -87,7 +88,6 @@ private VBox getSignUpBox() {

private Label getErrorLabel() {
errorLabel = new Label();
errorLabel.setPrefHeight(20);
return errorLabel;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
Expand All @@ -25,12 +26,14 @@ public class DbWrapperDonationsTest {
private Object[] cutoffDonation;
private Object[] freakyDonation;
private Object[] repeatingDonation;
private Object[] tooBigDonation;
private List<Object[]> donations;
private List<Object[]> donations2;
private List<Object[]> donations3;
private List<Object[]> repeatedDonations;
private List<Object[]> wrongFormatDonations;
private List<Object[]> wrongDatatypeDonations;
private List<Object[]> tooBigDonations;
private List<Object[]> nullList;

private static final int PRECISION = 5;
Expand All @@ -40,10 +43,10 @@ public class DbWrapperDonationsTest {
@BeforeEach
void init() {
this.db = new DbWrapper(true);
String[] firstNames = new String[] { "John", "Jane", "Cutoff", "Freaky", "Repeating" };
String[] lastNames = new String[] { "Doe", "Doe", "Joh", "Bill", "JoeJoe" };
String[] firstNames = new String[] { "John", "Jane", "Cutoff", "Freaky", "Repeating", "Big" };
String[] lastNames = new String[] { "Doe", "Doe", "Joh", "Bill", "JoeJoe", "Willy" };
this.users = new ArrayList<Object[]>();
for (int i = 0; i < 5; i++) {
for (int i = 0; i < firstNames.length; i++) {
Object[] row = new Object[6];
row[0] = i + 1;
row[1] = "Customer";
Expand Down Expand Up @@ -84,12 +87,23 @@ void init() {
this.wrongDatatypeDonations = new ArrayList<Object[]>();
this.wrongDatatypeDonations.add(freakyDonation);

this.tooBigDonation = new Object[] {
6, 6, 999999, new BigDecimal("9999999999999999999999999999999"),
new Timestamp(new Date().getTime()), "Azerbaijani technologies"
};
this.tooBigDonations = new ArrayList<Object[]>();
this.tooBigDonations.add(tooBigDonation);

Object[] nullRow = new Object[] {null, null, null, null, null, null};
this.nullList = new ArrayList<Object[]>();
this.nullList.add(nullRow);

this.db.connect();
this.db.exportUsers(users);
try {
this.db.exportUsers(users);
} catch (Exception e) {
// This exception won't happen
}
}

private static boolean donationEquals(Object[] array1, Object[] array2) {
Expand Down Expand Up @@ -150,7 +164,7 @@ public void wronglyDatatypedDonationsThrowsExpectedException() {
@Test
public void addingSameDonationTwiceThrowsExpectedException() {
assertTrue(this.db.importDonations((int) this.users.get(0)[0]).size() == 0);
assertEquals(1, this.db.exportDonations(this.donations));
assertDoesNotThrow(() -> assertEquals(1, this.db.exportDonations(this.donations)));
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> {
this.db.exportDonations(this.donations);
});
Expand All @@ -163,7 +177,7 @@ public void addingSameDonationTwiceThrowsExpectedException() {
public void addingSameDonationTwiceThrowsExpectedException2() {
assertTrue(this.db.importDonations((int) this.users.get(0)[0]).size() == 0);
assertTrue(this.db.importDonations((int) this.users.get(1)[0]).size() == 0);
assertEquals(2, this.db.exportDonations(this.donations2));
assertDoesNotThrow(() -> assertEquals(2, this.db.exportDonations(this.donations2)));
IllegalArgumentException exception = assertThrows(
IllegalArgumentException.class,
() -> {
Expand Down Expand Up @@ -212,8 +226,20 @@ public void addingDonationListWithNullInRowThrowsExpectedException() {
@Test
public void dataIsEmptyAfterExportingAndImportingEmptyList() {
assertTrue(this.db.importDonations((int) this.users.get(0)[0]).size() == 0);
assertEquals(0, this.db.exportDonations(new ArrayList<Object[]>()));
assertDoesNotThrow(() -> assertEquals(0, this.db.exportDonations(new ArrayList<Object[]>())));
assertTrue(this.db.importDonations((int) this.users.get(0)[0]).size() == 0);
assertTrue(this.db.disconnect());
}

@Test
public void exportTooBigNumberThrowsSQLException() {
SQLException exception = assertThrows(SQLException.class, () -> {
this.db.exportDonations(this.tooBigDonations);
});
assertEquals(
"An unexpected SQL exception has occurred. " +
"This might be caused by inserting an item that is too large.",
exception.getMessage()
);
}
}
27 changes: 25 additions & 2 deletions src/test/java/edu/group5/app/model/wrapper/DbWrapperUserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
Expand All @@ -20,12 +21,14 @@ public class DbWrapperUserTest {
private Object[] cutoffJoh;
private Object[] freakyBill;
private Object[] repeatingJoeJoe;
private Object[] bigWilly;
private List<Object[]> users;
private List<Object[]> users2;
private List<Object[]> users3;
private List<Object[]> repeatedUsers;
private List<Object[]> wrongFormatUsers;
private List<Object[]> wrongDatatypeUsers;
private List<Object[]> tooBigUsers;
private List<Object[]> nullList;

private DbWrapper db;
Expand Down Expand Up @@ -60,6 +63,12 @@ void init() {
this.wrongDatatypeUsers = new ArrayList<Object[]>();
this.wrongDatatypeUsers.add(freakyBill);

this.bigWilly = new Object[] {
6, "Customer", "Big", "Willy", "bigdwilly@waaaaaytoolargemail.com", "passssssssssssword"
};
this.tooBigUsers = new ArrayList<Object[]>();
this.tooBigUsers.add(this.bigWilly);

Object[] nullRow = new Object[] {null, null, null, null, null, null};
this.nullList = new ArrayList<Object[]>();
this.nullList.add(nullRow);
Expand Down Expand Up @@ -122,7 +131,7 @@ public void wronglyDatatypedUsersThrowsExpectedException() {
public void addingSameUserTwiceThrowsExpectedException() {
assertTrue(this.db.connect());
assertTrue(this.db.importUsers().size() == 0);
assertEquals(1, this.db.exportUsers(this.users));
assertDoesNotThrow(() -> assertEquals(1, this.db.exportUsers(this.users)));
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> {
this.db.exportUsers(this.users);
});
Expand All @@ -135,7 +144,7 @@ public void addingSameUserTwiceThrowsExpectedException() {
public void addingSameUserTwiceThrowsExpectedException2() {
assertTrue(this.db.connect());
assertTrue(this.db.importUsers().size() == 0);
assertEquals(2, this.db.exportUsers(this.users2));
assertDoesNotThrow(() -> assertEquals(2, this.db.exportUsers(this.users2)));
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> {
this.db.exportUsers(this.users);
});
Expand Down Expand Up @@ -179,4 +188,18 @@ public void addingUserListWithNullInRowThrowsExpectedException() {
assertTrue(this.db.disconnect());
assertEquals("One or more rows in data contains null values", exception.getMessage());
}

@Test
public void exportTooLongNameThrowsSQLException() {
assertTrue(this.db.connect());
assertTrue(this.db.importUsers().size() == 0);
SQLException exception = assertThrows(SQLException.class, () -> {
this.db.exportUsers(this.tooBigUsers);
});
assertEquals(
"An unexpected SQL exception has occurred. " +
"This might be caused by inserting an item that is too large.",
exception.getMessage()
);
}
}

0 comments on commit 380d1c6

Please sign in to comment.