← back to Handbag Authentication
scripts/test-price-crawler.js
145 lines
#!/usr/bin/env node
/**
* Test script for the daily price crawler
* Tests crawling a subset of data to verify everything works
*/
const PriceCrawler = require('./daily-price-crawler');
// Override brands for testing - just crawl a few items
const TEST_BRANDS = ['hermes', 'chanel'];
// Override the crawler to use test brands
class TestPriceCrawler extends PriceCrawler {
async crawlRetailer(retailerKey, retailer) {
console.log(`\n📍 TEST: Crawling ${retailer.name}...`);
// Only crawl test brands and limit to 5 items per brand
for (const brand of TEST_BRANDS) {
try {
console.log(` 🔍 TEST: Searching ${brand} bags (max 5 items)...`);
// Create mock data for testing
const mockItems = [
{
title: `${brand} Classic Bag - Excellent Condition`,
price: 3500 + Math.random() * 2000,
external_id: `test_${retailerKey}_${brand}_1`,
model: brand === 'hermes' ? 'Birkin' : 'Classic Flap',
condition: 'Excellent'
},
{
title: `${brand} Vintage Tote - Good Condition`,
price: 2000 + Math.random() * 1500,
external_id: `test_${retailerKey}_${brand}_2`,
model: brand === 'hermes' ? 'Garden Party' : '2.55',
condition: 'Good'
},
{
title: `${brand} Limited Edition - Like New`,
price: 5000 + Math.random() * 3000,
external_id: `test_${retailerKey}_${brand}_3`,
model: brand === 'hermes' ? 'Kelly' : 'Boy',
condition: 'Like New'
}
];
for (const item of mockItems) {
const data = {
retailer: retailer.name,
brand: this.normalizeBrand(brand),
item_name: item.title,
item_detail: item.title,
model: item.model,
condition: item.condition,
price_usd: item.price,
product_url: `https://example.com/product/${item.external_id}`,
image_url: `https://via.placeholder.com/300x300?text=${brand}`,
external_id: item.external_id,
crawl_date: new Date().toISOString().split('T')[0]
};
this.saveToDatabase(data);
this.crawlStats.totalItems++;
await this.delay(100); // Small delay for database operations
}
console.log(` ✓ TEST: Processed ${mockItems.length} ${brand} items`);
} catch (error) {
console.error(` ❌ TEST Error: ${error.message}`);
this.crawlStats.errors.push(`${retailer.name} - ${brand}: ${error.message}`);
}
}
}
}
// Run test
async function runTest() {
console.log('🧪 RUNNING PRICE CRAWLER TEST');
console.log('=' + '='.repeat(59));
console.log('This test will:');
console.log('1. Create the price_history table if it doesn\'t exist');
console.log('2. Insert test data for Hermes and Chanel bags');
console.log('3. Track first_seen_date and days_on_market');
console.log('4. Update analytics');
console.log('\n');
const crawler = new TestPriceCrawler();
await crawler.crawlAll();
// Query and display results
const sqlite3 = require('sqlite3').verbose();
const db = new sqlite3.Database('/root/Projects/handbag-authentication/data/handbags.db');
console.log('\n📊 TEST RESULTS - Recent Price History:');
console.log('=' + '='.repeat(59));
db.all(`
SELECT
retailer,
brand,
model,
condition,
price_usd,
first_seen_date,
last_updated,
days_on_market,
price_change,
crawl_date
FROM price_history
WHERE external_id LIKE 'test_%'
ORDER BY last_updated DESC, brand, retailer
LIMIT 20
`, (err, rows) => {
if (err) {
console.error('Error querying results:', err);
} else {
console.table(rows.map(row => ({
Retailer: row.retailer,
Brand: row.brand,
Model: row.model,
Condition: row.condition,
Price: `$${row.price_usd?.toFixed(2)}`,
'First Seen': row.first_seen_date,
'Last Updated': row.last_updated || 'N/A',
'Days on Market': row.days_on_market,
'Price Change': row.price_change ? `$${row.price_change.toFixed(2)}` : '$0'
})));
console.log(`\n✅ TEST COMPLETE - Found ${rows.length} test records in database`);
console.log('\n📅 The full crawler will run daily at 6 AM automatically via cron');
console.log('📝 Check logs at: /root/Projects/handbag-authentication/logs/price-crawl-cron.log');
}
db.close();
});
}
// Execute test
runTest().catch(error => {
console.error('Test failed:', error);
process.exit(1);
});