From 082c2a390977a2b34f6c843a18c9042fe3baa0e6 Mon Sep 17 00:00:00 2001 From: MatheaGjerde Date: Sun, 1 Mar 2026 22:22:57 +0100 Subject: [PATCH 01/10] Made the Donation class with accessor-methods and javadoc --- .../edu/group5/app/model/DBRepository.java | 4 + .../java/edu/group5/app/model/Repository.java | 4 + .../group5/app/model/donation/Donation.java | 74 ++++++++++++++++++- .../model/donation/DonationRepository.java | 4 + .../donation/DonationRepositoryTest.java | 4 + .../app/model/donation/DonationTest.java | 4 + 6 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 src/main/java/edu/group5/app/model/DBRepository.java create mode 100644 src/main/java/edu/group5/app/model/Repository.java create mode 100644 src/main/java/edu/group5/app/model/donation/DonationRepository.java create mode 100644 src/test/java/edu/group5/app/model/donation/DonationRepositoryTest.java create mode 100644 src/test/java/edu/group5/app/model/donation/DonationTest.java diff --git a/src/main/java/edu/group5/app/model/DBRepository.java b/src/main/java/edu/group5/app/model/DBRepository.java new file mode 100644 index 0000000..0a37add --- /dev/null +++ b/src/main/java/edu/group5/app/model/DBRepository.java @@ -0,0 +1,4 @@ +package edu.group5.app.model; + +public class DBRepository { +} diff --git a/src/main/java/edu/group5/app/model/Repository.java b/src/main/java/edu/group5/app/model/Repository.java new file mode 100644 index 0000000..53971bd --- /dev/null +++ b/src/main/java/edu/group5/app/model/Repository.java @@ -0,0 +1,4 @@ +package edu.group5.app.model; + +public class Repository { +} diff --git a/src/main/java/edu/group5/app/model/donation/Donation.java b/src/main/java/edu/group5/app/model/donation/Donation.java index a127439..353827d 100644 --- a/src/main/java/edu/group5/app/model/donation/Donation.java +++ b/src/main/java/edu/group5/app/model/donation/Donation.java @@ -1,5 +1,77 @@ package edu.group5.app.model.donation; +import java.math.BigDecimal; +import java.sql.Timestamp; + +/** + * Represents a verified donation made by a user to an organization. + */ public class Donation { - + private final int donationId; + private final int userId; + private final int organizationId; + private final BigDecimal amount; + private final Timestamp date; + private final String paymentMethod; + + /** + * Constructs a new Donation. + * + * @param donationId - the unique ID of this donation + * @param userId - the ID of the user making the donation + * @param organizationId - the ID of the organization receiving the donation + * @param amount - the donation amount + * @param date - the timestamp when the donation was made + * @param paymentMethod - the payment method used + */ + public Donation(int donationId, int userId, int organizationId, BigDecimal amount, Timestamp date, String paymentMethod) { + this.donationId = donationId; + this.userId = userId; + this.organizationId = organizationId; + this.amount = amount; + this.date = date; + this.paymentMethod = paymentMethod; + } + + /** + * @return the donation ID + */ + public int getDonationId(){ + return donationId; + } + + /** + * @return the user ID of the donator + */ + public int getUserId(){ + return userId; + } + + /** + * @return the organization ID that receives the donation + */ + public int getOrganizationId() { + return organizationId; + } + + /** + * @return the donated amount + */ + public BigDecimal getAmount() { + return amount; + } + + /** + * @return the timestamp of the donation + */ + public Timestamp getDate() { + return date; + } + + /** + * @return the payment method used + */ + public String getPaymentMethod() { + return paymentMethod; + } } diff --git a/src/main/java/edu/group5/app/model/donation/DonationRepository.java b/src/main/java/edu/group5/app/model/donation/DonationRepository.java new file mode 100644 index 0000000..f179b01 --- /dev/null +++ b/src/main/java/edu/group5/app/model/donation/DonationRepository.java @@ -0,0 +1,4 @@ +package edu.group5.app.model.donation; + +public class DonationRepository { +} diff --git a/src/test/java/edu/group5/app/model/donation/DonationRepositoryTest.java b/src/test/java/edu/group5/app/model/donation/DonationRepositoryTest.java new file mode 100644 index 0000000..e06a350 --- /dev/null +++ b/src/test/java/edu/group5/app/model/donation/DonationRepositoryTest.java @@ -0,0 +1,4 @@ +package edu.group5.app.model.donation; + +public class DonationRepositoryTest { +} 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..a4da95e --- /dev/null +++ b/src/test/java/edu/group5/app/model/donation/DonationTest.java @@ -0,0 +1,4 @@ +package edu.group5.app.model.donation; + +public class DonationTest { +} From 0b005bc25ac3ea16b5d78c5b4dbcfc4c4b812807 Mon Sep 17 00:00:00 2001 From: MatheaGjerde Date: Sun, 1 Mar 2026 22:26:39 +0100 Subject: [PATCH 02/10] Tested constructor and getters for Donation --- .../app/model/donation/DonationTest.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/test/java/edu/group5/app/model/donation/DonationTest.java b/src/test/java/edu/group5/app/model/donation/DonationTest.java index a4da95e..103378f 100644 --- a/src/test/java/edu/group5/app/model/donation/DonationTest.java +++ b/src/test/java/edu/group5/app/model/donation/DonationTest.java @@ -1,4 +1,23 @@ package edu.group5.app.model.donation; +import org.junit.jupiter.api.Test; + +import java.math.BigDecimal; +import java.sql.Timestamp; + +import static org.junit.jupiter.api.Assertions.assertEquals; + public class DonationTest { + @Test + void testConstructorAndGetters() { + Timestamp now = new Timestamp(System.currentTimeMillis()); + Donation donation = new Donation(1, 101, 202, new BigDecimal("500.0"), now, "Card"); + assertEquals(1, donation.getDonationId()); + assertEquals(101, donation.getUserId()); + assertEquals(202, donation.getOrganizationId()); + assertEquals(new BigDecimal("500.0"), donation.getAmount()); + assertEquals(now, donation.getDate()); + assertEquals("Card", donation.getPaymentMethod()); + } + } From d838299b0972089938dedbd390f31d9e5622b5b6 Mon Sep 17 00:00:00 2001 From: MatheaGjerde Date: Sun, 1 Mar 2026 23:19:30 +0100 Subject: [PATCH 03/10] feat: created Repository --- .../java/edu/group5/app/model/Repository.java | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/group5/app/model/Repository.java b/src/main/java/edu/group5/app/model/Repository.java index 53971bd..3d50bbe 100644 --- a/src/main/java/edu/group5/app/model/Repository.java +++ b/src/main/java/edu/group5/app/model/Repository.java @@ -1,4 +1,25 @@ package edu.group5.app.model; -public class Repository { +/** + * Represents a repository. + */ +public abstract class Repository { + /** + * The underlying data structure that holds the repository's content. + */ + protected Object content; + + /** + * Constructs a new Repository with the specified content. + * + * @param content the underlying data structure used to store entities + */ + protected Repository(Object content) { + this.content = content; + } + + /** + * @return content of the repo + */ + public abstract Object getContent(); } From ccdc4a59fc8ac896d5f7407bf0e2940018a864ea Mon Sep 17 00:00:00 2001 From: MatheaGjerde Date: Mon, 2 Mar 2026 10:53:32 +0100 Subject: [PATCH 04/10] feat: created the abstract class DBRepository --- .../edu/group5/app/model/DBRepository.java | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/group5/app/model/DBRepository.java b/src/main/java/edu/group5/app/model/DBRepository.java index 0a37add..7502809 100644 --- a/src/main/java/edu/group5/app/model/DBRepository.java +++ b/src/main/java/edu/group5/app/model/DBRepository.java @@ -1,4 +1,40 @@ package edu.group5.app.model; -public class DBRepository { + +import java.util.HashMap; + +/** + * Abstract base class for repositories that store their data + * in a database-related structure. + * + *

+ * Extends {@link Repository} and specifies that the content + * is stored as a {@link HashMap}. + *

+ */ +public abstract class DBRepository extends Repository { + /** + * The underlying data structure containing the repository entities. + */ + protected HashMap content; + + /** + * Constructs a DBRepository with the given content. + * + * @param content the HashMap used to store repository entities + */ + protected DBRepository(HashMap content) { + super(content); + this.content = content; + } + + /** + * Returns the underlying HashMap containing the repository entities. + * + * @return the repository content as a HashMap + */ + @Override + public HashMap getContent() { + return content; + } } From 5787e1273c7b338d9bba28125defb5f52f16edc3 Mon Sep 17 00:00:00 2001 From: MatheaGjerde Date: Mon, 2 Mar 2026 16:27:48 +0100 Subject: [PATCH 05/10] refactor: DBRepository to use generics --- src/main/java/edu/group5/app/model/DBRepository.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/edu/group5/app/model/DBRepository.java b/src/main/java/edu/group5/app/model/DBRepository.java index 7502809..3ec2945 100644 --- a/src/main/java/edu/group5/app/model/DBRepository.java +++ b/src/main/java/edu/group5/app/model/DBRepository.java @@ -12,18 +12,18 @@ * is stored as a {@link HashMap}. *

*/ -public abstract class DBRepository extends Repository { +public abstract class DBRepository extends Repository { /** * The underlying data structure containing the repository entities. */ - protected HashMap content; + protected HashMap content; /** * Constructs a DBRepository with the given content. * * @param content the HashMap used to store repository entities */ - protected DBRepository(HashMap content) { + protected DBRepository(HashMap content) { super(content); this.content = content; } @@ -34,7 +34,7 @@ protected DBRepository(HashMap content) { * @return the repository content as a HashMap */ @Override - public HashMap getContent() { + public HashMap getContent() { return content; } } From d60889057063c7d717e32a7898c4230e07ea6efc Mon Sep 17 00:00:00 2001 From: MatheaGjerde Date: Mon, 2 Mar 2026 17:47:33 +0100 Subject: [PATCH 06/10] feat: convert Donation to record and add throws to constructor --- .../group5/app/model/donation/Donation.java | 102 +++++++----------- 1 file changed, 39 insertions(+), 63 deletions(-) diff --git a/src/main/java/edu/group5/app/model/donation/Donation.java b/src/main/java/edu/group5/app/model/donation/Donation.java index 353827d..92adfbe 100644 --- a/src/main/java/edu/group5/app/model/donation/Donation.java +++ b/src/main/java/edu/group5/app/model/donation/Donation.java @@ -5,73 +5,49 @@ /** * Represents a verified donation made by a user to an organization. + * @param donationId - the unique ID of this donation + * @param userId - the ID of the user making the donation + * @param organizationId - the ID of the organization receiving the donation + * @param amount - the donation amount + * @param date - the timestamp when the donation was made + * @param paymentMethod - the payment method used */ -public class Donation { - private final int donationId; - private final int userId; - private final int organizationId; - private final BigDecimal amount; - private final Timestamp date; - private final String paymentMethod; +public record Donation( + int donationId, + int userId, + int organizationId, + BigDecimal amount, + Timestamp date, + String paymentMethod) { /** - * Constructs a new Donation. + * Constructor with throws. * - * @param donationId - the unique ID of this donation - * @param userId - the ID of the user making the donation - * @param organizationId - the ID of the organization receiving the donation - * @param amount - the donation amount - * @param date - the timestamp when the donation was made - * @param paymentMethod - the payment method used + * @param donationId - throws if donationID is negative or 0. + * @param userId - throws if userID is negative or 0. + * @param organizationId - throws if organizationID is negative or 0. + * @param amount - throws if amount is negative or null. + * @param date - throws if date is null. + * @param paymentMethod - throws if payment is null or blank. */ - public Donation(int donationId, int userId, int organizationId, BigDecimal amount, Timestamp date, String paymentMethod) { - this.donationId = donationId; - this.userId = userId; - this.organizationId = organizationId; - this.amount = amount; - this.date = date; - this.paymentMethod = paymentMethod; - } - - /** - * @return the donation ID - */ - public int getDonationId(){ - return donationId; - } - - /** - * @return the user ID of the donator - */ - public int getUserId(){ - return userId; - } - - /** - * @return the organization ID that receives the donation - */ - public int getOrganizationId() { - return organizationId; - } - - /** - * @return the donated amount - */ - public BigDecimal getAmount() { - return amount; - } - - /** - * @return the timestamp of the donation - */ - public Timestamp getDate() { - return date; - } - - /** - * @return the payment method used - */ - public String getPaymentMethod() { - return paymentMethod; + public Donation { + if (donationId <= 0) { + throw new IllegalArgumentException("Donation ID must be positive"); + } + if (userId <= 0) { + throw new IllegalArgumentException("User ID must be positive"); + } + if (organizationId <= 0) { + throw new IllegalArgumentException("Organization ID must be positive"); + } + if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) { + throw new IllegalArgumentException("Amount must be positive and not null"); + } + if (date == null) { + throw new IllegalArgumentException("Date must not be null"); + } + if (paymentMethod == null || paymentMethod.isBlank()) { + throw new IllegalArgumentException("Payment method must not be empty"); + } } } From 3361b26d9c6e9e53389fa69ce93625bc04d9059d Mon Sep 17 00:00:00 2001 From: MatheaGjerde Date: Mon, 2 Mar 2026 21:32:52 +0100 Subject: [PATCH 07/10] feat: implement DonationRepository with sorting and filtering methods --- .../model/donation/DonationRepository.java | 108 +++++++++++++++++- 1 file changed, 107 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/group5/app/model/donation/DonationRepository.java b/src/main/java/edu/group5/app/model/donation/DonationRepository.java index f179b01..596ea60 100644 --- a/src/main/java/edu/group5/app/model/donation/DonationRepository.java +++ b/src/main/java/edu/group5/app/model/donation/DonationRepository.java @@ -1,4 +1,110 @@ package edu.group5.app.model.donation; -public class DonationRepository { +import edu.group5.app.model.DBRepository; + +import java.util.Comparator; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Repository class for Donation. + * + *

+ * Extends {@link DBRepository} and manages Donation entities. + *

+ */ +public class DonationRepository extends DBRepository { + private final HashMap content; + + /** + * Constructs DonationRepository using Hashmap, + * and extends the content from DBRepository. + * @param content the underlying map used to store donations, + * where the key represents the donation ID + */ + public DonationRepository(HashMap content){ + super(content); + this.content = content; + } + + /** + * Adds a new donation to the repository + *

+ * The donation is stored using its {@code donationId} as the key. + * If a donation with the same ID already exists, the donation + * will not be added. + *

+ * + * @param donation the donation to add + * @return {@code true} if the donation was successfully added, and + * {@code false} if a donation with the same ID already exists + */ + public boolean addDonation(Donation donation) { + if(content.containsKey(donation.donationId())){ + return false; + } + content.put(donation.donationId(), donation); + return true; + } + + /** + * Returns all donations sorted by date (ascending). + * + *

+ * The returned map preserves the sorted order. + *

+ * + * @return a new {@link HashMap} containing the donations sorted by date + */ + public HashMap sortByDate(){ + return content.entrySet().stream() + .sorted(Map.Entry.comparingByValue( + Comparator.comparing(Donation::date))) + .collect(Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (e1, e2) -> e1, + LinkedHashMap::new)); + } + + /** + * Returns all donations sorted by amount (ascending). + * + *

+ * The returned map preserves the sorted order from lowest to highest amount. + *

+ * + * @return a new {@link HashMap} containing the donations sorted by amount. + */ + public HashMap sortByAmount() { + return content.entrySet().stream() + .sorted(Map.Entry.comparingByValue( + Comparator.comparing(Donation::amount))) + .collect(Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (e1, e2) -> e1, + LinkedHashMap::new + )); + } + + /** + * Returns all donations associated with a specific organization. + * + * @param orgNumber the organization ID to filter by + * @return a map containing all donations that belong to the given organization + */ + public HashMap filterByOrganization(int orgNumber) { + return content.entrySet() + .stream() + .filter(entry -> entry.getValue().organizationId() == orgNumber) + .collect(Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (e1, e2) -> e1, + LinkedHashMap::new + )); + } } From ae7f856e185a4c59ae38f2c957f8e6201108e97d Mon Sep 17 00:00:00 2001 From: MatheaGjerde Date: Mon, 2 Mar 2026 22:18:20 +0100 Subject: [PATCH 08/10] feat: added throw exceptions to DonationRepository --- .../group5/app/model/donation/DonationRepository.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/group5/app/model/donation/DonationRepository.java b/src/main/java/edu/group5/app/model/donation/DonationRepository.java index 596ea60..339e7ca 100644 --- a/src/main/java/edu/group5/app/model/donation/DonationRepository.java +++ b/src/main/java/edu/group5/app/model/donation/DonationRepository.java @@ -25,6 +25,9 @@ public class DonationRepository extends DBRepository { * where the key represents the donation ID */ public DonationRepository(HashMap content){ + if (content == null) { + throw new IllegalArgumentException("Content cannot be null"); + } super(content); this.content = content; } @@ -42,7 +45,10 @@ public DonationRepository(HashMap content){ * {@code false} if a donation with the same ID already exists */ public boolean addDonation(Donation donation) { - if(content.containsKey(donation.donationId())){ + if (donation == null) { + throw new IllegalArgumentException("Donation cannot be null"); + } + if (content.containsKey(donation.donationId())){ return false; } content.put(donation.donationId(), donation); @@ -97,6 +103,9 @@ public HashMap sortByAmount() { * @return a map containing all donations that belong to the given organization */ public HashMap filterByOrganization(int orgNumber) { + if (orgNumber <= 0) { + throw new IllegalArgumentException("Organization number must be positive"); + } return content.entrySet() .stream() .filter(entry -> entry.getValue().organizationId() == orgNumber) From b0614fd87a8dc55dd8410fb9edf7a608befe5454 Mon Sep 17 00:00:00 2001 From: MatheaGjerde Date: Tue, 3 Mar 2026 15:25:18 +0100 Subject: [PATCH 09/10] test: added negative tests for DonationTest --- .../app/model/donation/DonationTest.java | 94 +++++++++++++++++-- 1 file changed, 85 insertions(+), 9 deletions(-) diff --git a/src/test/java/edu/group5/app/model/donation/DonationTest.java b/src/test/java/edu/group5/app/model/donation/DonationTest.java index 103378f..f8f9069 100644 --- a/src/test/java/edu/group5/app/model/donation/DonationTest.java +++ b/src/test/java/edu/group5/app/model/donation/DonationTest.java @@ -1,23 +1,99 @@ package edu.group5.app.model.donation; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.math.BigDecimal; import java.sql.Timestamp; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; public class DonationTest { + + private String expectedMessage; + private int donationId1; + private int userId1; + private int organizationId1; + private BigDecimal amount1; + private Timestamp date1; + private String paymentMethod1; + private Donation donation; + + @BeforeEach + void setUp(){ + donationId1 = 1; + userId1 = 101; + organizationId1 = 202; + amount1 = new BigDecimal("500.0"); + date1 = new Timestamp(System.currentTimeMillis()); + paymentMethod1 = "Card"; + donation = new Donation(donationId1, userId1, + organizationId1, amount1, date1, paymentMethod1); + + } + + private void exceptionTest(int donationId, int userId, + int organizationId, BigDecimal amount, + Timestamp date, String paymentMethod) { + IllegalArgumentException exception = assertThrows( + IllegalArgumentException.class, () -> new Donation( + donationId, userId, organizationId, amount, date, paymentMethod) + ); + assertEquals(expectedMessage, exception.getMessage()); + } + + @Test + void testIfDonationGetsDonationValues() { + + assertEquals(1, donation.donationId()); + assertEquals(101, donation.userId()); + assertEquals(202, donation.organizationId()); + assertEquals(new BigDecimal("500.0"), donation.amount()); + assertEquals(date1, donation.date()); + assertEquals("Card", donation.paymentMethod()); + } + + @Test + void testIfThrowsExceptionWhenDonationIdIsNotPositive() { + expectedMessage = "Donation ID must be positive"; + exceptionTest(0, userId1, organizationId1, + amount1, date1, paymentMethod1); + } + + @Test + void testIfThrowsExceptionWhenUserIdIsNotPositive() { + expectedMessage = "User ID must be positive"; + exceptionTest(donationId1, -1, organizationId1, + amount1, date1, paymentMethod1); + } + @Test + void testIfThrowsExceptionWhenOrganizationIdIsNotPositive() { + expectedMessage = "Organization ID must be positive"; + exceptionTest(donationId1, userId1, 0, + amount1, date1, paymentMethod1); + } @Test - void testConstructorAndGetters() { - Timestamp now = new Timestamp(System.currentTimeMillis()); - Donation donation = new Donation(1, 101, 202, new BigDecimal("500.0"), now, "Card"); - assertEquals(1, donation.getDonationId()); - assertEquals(101, donation.getUserId()); - assertEquals(202, donation.getOrganizationId()); - assertEquals(new BigDecimal("500.0"), donation.getAmount()); - assertEquals(now, donation.getDate()); - assertEquals("Card", donation.getPaymentMethod()); + void testIfThrowsExceptionWhenAmountIsNotPositive() { + expectedMessage = "Amount must be positive and not null"; + exceptionTest(donationId1, userId1, organizationId1, + new BigDecimal("0.00"), date1, paymentMethod1); } + @Test + void testIfThrowsExceptionWhenDateIsNull() { + expectedMessage = "Date must not be null"; + exceptionTest(donationId1, userId1, organizationId1, + amount1, null, paymentMethod1); + } + @Test + void testIfThrowsExceptionWhenPaymentMethodIsNullOrEmpty() { + expectedMessage = "Payment method must not be empty"; + exceptionTest(donationId1, userId1, organizationId1, + amount1, date1, null); + exceptionTest(donationId1, userId1, organizationId1, + amount1, date1, " "); + + } + } From 632e8fad541a3a824cd3f1a01b4c5b4784785404 Mon Sep 17 00:00:00 2001 From: MatheaGjerde Date: Tue, 3 Mar 2026 18:02:23 +0100 Subject: [PATCH 10/10] test: added positive and negative tests to DonationRepositoryTest --- .../donation/DonationRepositoryTest.java | 184 ++++++++++++++++++ 1 file changed, 184 insertions(+) diff --git a/src/test/java/edu/group5/app/model/donation/DonationRepositoryTest.java b/src/test/java/edu/group5/app/model/donation/DonationRepositoryTest.java index e06a350..b55ef57 100644 --- a/src/test/java/edu/group5/app/model/donation/DonationRepositoryTest.java +++ b/src/test/java/edu/group5/app/model/donation/DonationRepositoryTest.java @@ -1,4 +1,188 @@ package edu.group5.app.model.donation; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.math.BigDecimal; +import java.sql.Timestamp; +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.*; + public class DonationRepositoryTest { + private DonationRepository repo; + private Timestamp now; + private Donation donation1; + private Donation donation2; + private Donation donation3; + private Donation donation4; + + @BeforeEach + void setUp() { + repo = new DonationRepository(new HashMap<>()); + + Timestamp ts1 = Timestamp.valueOf("2025-01-01 10:00:00"); + Timestamp ts2 = Timestamp.valueOf("2025-01-01 10:00:01"); + now = new Timestamp(System.currentTimeMillis()); + + donation1 = new Donation(1, 102, 202, new BigDecimal("500.0"), ts1, "Card"); + donation2 = new Donation(2, 102, 202, new BigDecimal("500.0"), ts2, "PayPal"); + donation3 = new Donation(3, 103, 203, new BigDecimal("200.0"), now, "PayPal"); + donation4 = new Donation(1, 101, 201, new BigDecimal("500.0"), now, "Card"); + + + } + @Test + void testThrowsExceptionIfContentIsNull() { + IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, + () -> new DonationRepository(null)); + assertEquals("Content cannot be null", thrown.getMessage()); + } + + @Test + void testAddDonation() { + assertTrue(repo.addDonation(donation1)); + assertEquals(1, repo.getContent().size()); + + assertTrue(repo.addDonation(donation3)); + assertEquals(2, repo.getContent().size()); + } + @Test + void testAddDonationWithDuplicateId() { + assertTrue(repo.addDonation(donation1)); + assertFalse(repo.addDonation(donation4)); + assertEquals(1, repo.getContent().size()); + } + @Test + void testAddNullDonation() { + IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, + () -> repo.addDonation(null)); + assertEquals("Donation cannot be null",thrown.getMessage()); + } + + @Test + void testSortByDate() { + repo.addDonation(donation3); + repo.addDonation(donation1); + repo.addDonation(donation2); + + HashMap sorted = repo.sortByDate(); + + Integer[] keys = sorted.keySet().toArray(new Integer[0]); + assertEquals(1, keys[0]); + assertEquals(2, keys[1]); + assertEquals(3, keys[2]); + + } + @Test + void testSortByDateWithSameDate() { + + repo.addDonation(donation3); + repo.addDonation(donation4); + + HashMap sorted = repo.sortByDate(); + + assertEquals(2, sorted.size()); + assertTrue(sorted.containsKey(1)); + assertTrue(sorted.containsKey(3)); + } + @Test + void testSortByDateWithSameDonation() { + Timestamp sameDate = Timestamp.valueOf("2025-01-01 10:00:00"); + + Donation d1 = new Donation(1, 101, 201, + new BigDecimal("500.0"), sameDate, "Card"); + + repo.addDonation(d1); + repo.addDonation(donation4); + + HashMap sorted = repo.sortByDate(); + + assertEquals(1, sorted.size()); + assertTrue(sorted.containsKey(1)); + assertFalse(sorted.containsKey(2)); + } + @Test + void TestSortByAmountTest() { + repo.addDonation(donation2); + repo.addDonation(donation3); + + HashMap sorted = repo.sortByAmount(); + Integer[] keys = sorted.keySet().toArray(new Integer[0]); + + assertEquals(3, keys[0]); + assertEquals(2, keys[1]); + + + } + @Test + void testSortByAmountWithSameAmount() { + repo.addDonation(donation1); + repo.addDonation(donation2); + + HashMap sorted = repo.sortByAmount(); + + assertEquals(2, sorted.size()); + assertTrue(sorted.containsKey(1)); + assertTrue(sorted.containsKey(2)); + } + @Test + void testSortByAmountWithSameDonation() { + + Donation d1 = new Donation(1, 101, 201, + new BigDecimal("500.0"), now, "Card"); + + repo.addDonation(d1); + repo.addDonation(donation4); + + HashMap sorted = repo.sortByAmount(); + + assertEquals(1, sorted.size()); + assertTrue(sorted.containsKey(1)); + assertFalse(sorted.containsKey(2)); + } + @Test + void testFilterByOrganization() { + repo.addDonation(donation1); + repo.addDonation(donation2); + + HashMap filtered = repo.filterByOrganization(202); + + assertEquals(2, filtered.size()); + assertTrue(filtered.containsKey(1)); + assertTrue(filtered.containsKey(2)); + assertFalse(filtered.containsKey(3)); + } + @Test + void testFilterByOrganizationNoMatch() { + repo.addDonation(donation1); + repo.addDonation(donation2); + + HashMap filtered = repo.filterByOrganization(999); + + assertTrue(filtered.isEmpty()); + } + @Test + void testThrowsExceptionWhenOrgNumberIsNegative() { + IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, + () -> repo.filterByOrganization(-1)); + assertEquals("Organization number must be positive",thrown.getMessage()); + } + @Test + void testFilterByOrganizationWithSameDonation() { + Timestamp sameDate = Timestamp.valueOf("2025-01-01 10:00:00"); + + Donation d1 = new Donation(1, 101, 201, + new BigDecimal("500.0"), sameDate, "Card"); + + repo.addDonation(d1); + repo.addDonation(donation4); + + HashMap sorted = repo.filterByOrganization(201); + + assertEquals(1, sorted.size()); + assertTrue(sorted.containsKey(1)); + assertFalse(sorted.containsKey(2)); + } + }