382 lines
10 KiB
Java
382 lines
10 KiB
Java
package auctiora;
|
|
|
|
import org.junit.jupiter.api.*;
|
|
|
|
import java.io.IOException;
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Paths;
|
|
import java.sql.SQLException;
|
|
import java.time.LocalDateTime;
|
|
|
|
import static org.junit.jupiter.api.Assertions.*;
|
|
|
|
/**
|
|
* Test cases for TroostwijkMonitor.
|
|
* Tests monitoring orchestration, bid tracking, and notification triggers.
|
|
*/
|
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
|
class TroostwijkMonitorTest {
|
|
|
|
private String testDbPath;
|
|
private TroostwijkMonitor monitor;
|
|
|
|
@BeforeAll
|
|
void setUp() throws SQLException, IOException {
|
|
testDbPath = "test_monitor_" + System.currentTimeMillis() + ".db";
|
|
|
|
// Initialize with non-existent YOLO models (disabled mode)
|
|
monitor = new TroostwijkMonitor(
|
|
testDbPath,
|
|
"desktop",
|
|
"non_existent.cfg",
|
|
"non_existent.weights",
|
|
"non_existent.txt"
|
|
);
|
|
}
|
|
|
|
@AfterAll
|
|
void tearDown() throws Exception {
|
|
Files.deleteIfExists(Paths.get(testDbPath));
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("Should initialize monitor successfully")
|
|
void testMonitorInitialization() {
|
|
assertNotNull(monitor);
|
|
assertNotNull(monitor.getDb());
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("Should print database stats without error")
|
|
void testPrintDatabaseStats() {
|
|
assertDoesNotThrow(() -> monitor.printDatabaseStats());
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("Should process pending images without error")
|
|
void testProcessPendingImages() {
|
|
assertDoesNotThrow(() -> monitor.processPendingImages());
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("Should handle empty database gracefully")
|
|
void testEmptyDatabaseHandling() throws SQLException {
|
|
var auctions = monitor.getDb().getAllAuctions();
|
|
var lots = monitor.getDb().getAllLots();
|
|
|
|
assertNotNull(auctions);
|
|
assertNotNull(lots);
|
|
assertTrue(auctions.isEmpty() || auctions.size() >= 0);
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("Should track lots in database")
|
|
void testLotTracking() throws SQLException {
|
|
// Insert test lot
|
|
var lot = new Lot(
|
|
11111, 22222,
|
|
"Test Forklift",
|
|
"Electric forklift in good condition",
|
|
"Toyota",
|
|
"Electric",
|
|
2020,
|
|
"Machinery",
|
|
1500.00,
|
|
"EUR",
|
|
"https://example.com/lot/22222",
|
|
LocalDateTime.now().plusDays(1),
|
|
false
|
|
);
|
|
|
|
monitor.getDb().upsertLot(lot);
|
|
|
|
var lots = monitor.getDb().getAllLots();
|
|
assertTrue(lots.stream().anyMatch(l -> l.lotId() == 22222));
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("Should monitor lots closing soon")
|
|
void testClosingSoonMonitoring() throws SQLException {
|
|
// Insert lot closing in 4 minutes
|
|
var closingSoon = new Lot(
|
|
33333, 44444,
|
|
"Closing Soon Item",
|
|
"Description",
|
|
"",
|
|
"",
|
|
0,
|
|
"Category",
|
|
100.00,
|
|
"EUR",
|
|
"https://example.com/lot/44444",
|
|
LocalDateTime.now().plusMinutes(4),
|
|
false
|
|
);
|
|
|
|
monitor.getDb().upsertLot(closingSoon);
|
|
|
|
var lots = monitor.getDb().getActiveLots();
|
|
var found = lots.stream()
|
|
.filter(l -> l.lotId() == 44444)
|
|
.findFirst()
|
|
.orElse(null);
|
|
|
|
assertNotNull(found);
|
|
assertTrue(found.minutesUntilClose() < 30);
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("Should identify lots with time remaining")
|
|
void testTimeRemainingCalculation() throws SQLException {
|
|
var futureLot = new Lot(
|
|
55555, 66666,
|
|
"Future Lot",
|
|
"Description",
|
|
"",
|
|
"",
|
|
0,
|
|
"Category",
|
|
200.00,
|
|
"EUR",
|
|
"https://example.com/lot/66666",
|
|
LocalDateTime.now().plusHours(2),
|
|
false
|
|
);
|
|
|
|
monitor.getDb().upsertLot(futureLot);
|
|
|
|
var lots = monitor.getDb().getActiveLots();
|
|
var found = lots.stream()
|
|
.filter(l -> l.lotId() == 66666)
|
|
.findFirst()
|
|
.orElse(null);
|
|
|
|
assertNotNull(found);
|
|
assertTrue(found.minutesUntilClose() > 60);
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("Should handle lots without closing time")
|
|
void testLotsWithoutClosingTime() throws SQLException {
|
|
var noClosing = new Lot(
|
|
77777, 88888,
|
|
"No Closing Time",
|
|
"Description",
|
|
"",
|
|
"",
|
|
0,
|
|
"Category",
|
|
150.00,
|
|
"EUR",
|
|
"https://example.com/lot/88888",
|
|
null,
|
|
false
|
|
);
|
|
|
|
monitor.getDb().upsertLot(noClosing);
|
|
|
|
var lots = monitor.getDb().getActiveLots();
|
|
var found = lots.stream()
|
|
.filter(l -> l.lotId() == 88888)
|
|
.findFirst()
|
|
.orElse(null);
|
|
|
|
assertNotNull(found);
|
|
assertNull(found.closingTime());
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("Should track notification status")
|
|
void testNotificationStatusTracking() throws SQLException {
|
|
var lot = new Lot(
|
|
99999, 11110,
|
|
"Test Notification",
|
|
"Description",
|
|
"",
|
|
"",
|
|
0,
|
|
"Category",
|
|
100.00,
|
|
"EUR",
|
|
"https://example.com/lot/11110",
|
|
LocalDateTime.now().plusMinutes(3),
|
|
false
|
|
);
|
|
|
|
monitor.getDb().upsertLot(lot);
|
|
|
|
// Update notification flag
|
|
var notified = new Lot(
|
|
99999, 11110,
|
|
"Test Notification",
|
|
"Description",
|
|
"",
|
|
"",
|
|
0,
|
|
"Category",
|
|
100.00,
|
|
"EUR",
|
|
"https://example.com/lot/11110",
|
|
LocalDateTime.now().plusMinutes(3),
|
|
true
|
|
);
|
|
|
|
monitor.getDb().updateLotNotificationFlags(notified);
|
|
|
|
var lots = monitor.getDb().getActiveLots();
|
|
var found = lots.stream()
|
|
.filter(l -> l.lotId() == 11110)
|
|
.findFirst()
|
|
.orElse(null);
|
|
|
|
assertNotNull(found);
|
|
assertTrue(found.closingNotified());
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("Should update bid amounts")
|
|
void testBidAmountUpdates() throws SQLException {
|
|
var lot = new Lot(
|
|
12121, 13131,
|
|
"Bid Update Test",
|
|
"Description",
|
|
"",
|
|
"",
|
|
0,
|
|
"Category",
|
|
100.00,
|
|
"EUR",
|
|
"https://example.com/lot/13131",
|
|
LocalDateTime.now().plusDays(1),
|
|
false
|
|
);
|
|
|
|
monitor.getDb().upsertLot(lot);
|
|
|
|
// Simulate bid increase
|
|
var higherBid = new Lot(
|
|
12121, 13131,
|
|
"Bid Update Test",
|
|
"Description",
|
|
"",
|
|
"",
|
|
0,
|
|
"Category",
|
|
250.00,
|
|
"EUR",
|
|
"https://example.com/lot/13131",
|
|
LocalDateTime.now().plusDays(1),
|
|
false
|
|
);
|
|
|
|
monitor.getDb().updateLotCurrentBid(higherBid);
|
|
|
|
var lots = monitor.getDb().getActiveLots();
|
|
var found = lots.stream()
|
|
.filter(l -> l.lotId() == 13131)
|
|
.findFirst()
|
|
.orElse(null);
|
|
|
|
assertNotNull(found);
|
|
assertEquals(250.00, found.currentBid(), 0.01);
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("Should handle multiple concurrent lot updates")
|
|
void testConcurrentLotUpdates() throws InterruptedException, SQLException {
|
|
Thread t1 = new Thread(() -> {
|
|
try {
|
|
for (int i = 0; i < 5; i++) {
|
|
monitor.getDb().upsertLot(new Lot(
|
|
20000 + i, 30000 + i, "Concurrent " + i, "Desc", "", "", 0, "Cat",
|
|
100.0, "EUR", "https://example.com/" + i, null, false
|
|
));
|
|
}
|
|
} catch (SQLException e) {
|
|
fail("Thread 1 failed: " + e.getMessage());
|
|
}
|
|
});
|
|
|
|
Thread t2 = new Thread(() -> {
|
|
try {
|
|
for (int i = 5; i < 10; i++) {
|
|
monitor.getDb().upsertLot(new Lot(
|
|
20000 + i, 30000 + i, "Concurrent " + i, "Desc", "", "", 0, "Cat",
|
|
200.0, "EUR", "https://example.com/" + i, null, false
|
|
));
|
|
}
|
|
} catch (SQLException e) {
|
|
fail("Thread 2 failed: " + e.getMessage());
|
|
}
|
|
});
|
|
|
|
t1.start();
|
|
t2.start();
|
|
t1.join();
|
|
t2.join();
|
|
|
|
var lots = monitor.getDb().getActiveLots();
|
|
long count = lots.stream()
|
|
.filter(l -> l.lotId() >= 30000 && l.lotId() < 30010)
|
|
.count();
|
|
|
|
assertTrue(count >= 10);
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("Should schedule monitoring without error")
|
|
void testScheduleMonitoring() {
|
|
// This just tests that scheduling doesn't throw
|
|
// Actual monitoring would run in background
|
|
assertDoesNotThrow(() -> {
|
|
// Don't actually start monitoring in test
|
|
// Just verify monitor is ready
|
|
assertNotNull(monitor);
|
|
});
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("Should handle database with auctions and lots")
|
|
void testDatabaseWithData() throws SQLException {
|
|
// Insert auction
|
|
var auction = new AuctionInfo(
|
|
40000,
|
|
"Test Auction",
|
|
"Amsterdam, NL",
|
|
"Amsterdam",
|
|
"NL",
|
|
"https://example.com/auction/40000",
|
|
"A7",
|
|
10,
|
|
LocalDateTime.now().plusDays(2)
|
|
);
|
|
|
|
monitor.getDb().upsertAuction(auction);
|
|
|
|
// Insert related lot
|
|
var lot = new Lot(
|
|
40000, 50000,
|
|
"Test Lot",
|
|
"Description",
|
|
"",
|
|
"",
|
|
0,
|
|
"Category",
|
|
500.00,
|
|
"EUR",
|
|
"https://example.com/lot/50000",
|
|
LocalDateTime.now().plusDays(2),
|
|
false
|
|
);
|
|
|
|
monitor.getDb().upsertLot(lot);
|
|
|
|
// Verify
|
|
var auctions = monitor.getDb().getAllAuctions();
|
|
var lots = monitor.getDb().getAllLots();
|
|
|
|
assertTrue(auctions.stream().anyMatch(a -> a.auctionId() == 40000));
|
|
assertTrue(lots.stream().anyMatch(l -> l.lotId() == 50000));
|
|
}
|
|
}
|