package com.auction; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.opencv.core.Core; import java.io.File; import java.sql.SQLException; import java.util.List; import static org.junit.jupiter.api.Assertions.*; /** * Test case for TroostwijkScraper that verifies auction discovery and data persistence. * Uses a temporary test database to verify that: * 1. Dutch auctions are correctly discovered from the live page * 2. Auction properties (sale IDs, titles, etc.) are valid * 3. Data is correctly persisted to the database */ public class TroostwijkScraperTest { private TroostwijkScraper scraper; private String testDatabasePath; @BeforeAll public static void loadOpenCV() { // Load native OpenCV library before any tests run try { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); System.out.println("✓ OpenCV native library loaded successfully"); } catch (UnsatisfiedLinkError e) { System.err.println("⚠️ Warning: Could not load OpenCV native library"); System.err.println(" Tests will run without object detection support"); } } @BeforeEach public void setUp() throws SQLException, java.io.IOException { // Create temporary test database testDatabasePath = "test_auctions_" + System.currentTimeMillis() + ".db"; // Initialize scraper with test database (no YOLO models needed for this test) // Using non-existent paths for YOLO files will disable object detection scraper = new TroostwijkScraper( testDatabasePath, "desktop", "", "nonexistent/yolov4.cfg", "nonexistent/yolov4.weights", "nonexistent/coco.names" ); } @AfterEach public void tearDown() { // Clean up test database File dbFile = new File(testDatabasePath); if (dbFile.exists()) { dbFile.delete(); } } @Test public void testDiscoverDutchAuctions() { // Discover auctions from the live page List auctions = scraper.discoverDutchAuctions(); // Verify that auctions were found assertNotNull(auctions, "Auctions list should not be null"); assertFalse(auctions.isEmpty(), "Should find at least one Dutch auction"); // Verify that all sale IDs are positive integers for (Integer saleId : auctions) { assertNotNull(saleId, "Sale ID should not be null"); assertTrue(saleId > 0, "Sale ID should be positive: " + saleId); } // Verify no duplicate sale IDs long uniqueCount = auctions.stream().distinct().count(); assertEquals(auctions.size(), uniqueCount, "All sale IDs should be unique"); System.out.println("✓ Found " + auctions.size() + " unique Dutch auctions"); System.out.println("✓ Sale IDs: " + auctions); } @Test public void testFetchAndPersistAuctionData() throws SQLException { // First, discover auctions List auctions = scraper.discoverDutchAuctions(); assertFalse(auctions.isEmpty(), "Need at least one auction to test"); // Take the first auction and fetch its lots Integer firstSaleId = auctions.get(0); System.out.println("Testing with sale ID: " + firstSaleId); scraper.fetchLotsForSale(firstSaleId); // Verify data was persisted to database List lotsInDb = scraper.db.getAllLots(); assertNotNull(lotsInDb, "Lots list should not be null"); assertFalse(lotsInDb.isEmpty(), "Should have persisted at least one lot"); // Verify lot properties for (TroostwijkScraper.Lot lot : lotsInDb) { assertEquals(firstSaleId.intValue(), lot.saleId, "Lot should belong to the correct sale"); assertTrue(lot.lotId > 0, "Lot ID should be positive"); assertNotNull(lot.title, "Lot title should not be null"); assertFalse(lot.title.isEmpty(), "Lot title should not be empty"); assertNotNull(lot.url, "Lot URL should not be null"); assertTrue(lot.url.startsWith("https://"), "Lot URL should be valid"); assertTrue(lot.currentBid >= 0, "Current bid should be non-negative"); } System.out.println("✓ Successfully persisted " + lotsInDb.size() + " lots to database"); System.out.println("✓ All lot properties are valid"); } @Test public void testDatabaseSchema() throws SQLException { // Verify that the database schema was created correctly List lots = scraper.db.getAllLots(); assertNotNull(lots, "Should be able to query lots table"); int imageCount = scraper.db.getImageCount(); assertTrue(imageCount >= 0, "Image count should be non-negative"); List activeLots = scraper.db.getActiveLots(); assertNotNull(activeLots, "Should be able to query active lots"); System.out.println("✓ Database schema is valid and queryable"); } @Test public void testAuctionProperties() { List auctions = scraper.discoverDutchAuctions(); assertFalse(auctions.isEmpty(), "Should find auctions"); // Test that we can fetch data for multiple auctions int auctionsToTest = Math.min(2, auctions.size()); for (int i = 0; i < auctionsToTest; i++) { Integer saleId = auctions.get(i); System.out.println("Testing auction " + (i + 1) + ": " + saleId); // This should not throw an exception assertDoesNotThrow(() -> scraper.fetchLotsForSale(saleId), "Should be able to fetch lots for sale " + saleId); } System.out.println("✓ Successfully tested " + auctionsToTest + " auctions"); } }