#!/usr/bin/env node /** * Timestamp Validation Test * Simple test to verify our timestamp validation logic works correctly */ const AlertManager = require('./server/alertManager'); function testTimestampValidation() { console.log('šŸ” Testing Timestamp Validation Logic...\n'); const alertManager = new AlertManager(); try { console.log('1. Testing with valid triggeredAt...'); const alertWithTriggeredAt = { triggeredAt: 1640995200000, lastUpdate: 1640995260000 }; const timestamp1 = alertManager.getValidTimestamp(alertWithTriggeredAt); console.log(` Result: ${timestamp1} (should be ${alertWithTriggeredAt.triggeredAt})`); if (timestamp1 !== alertWithTriggeredAt.triggeredAt) { throw new Error('Should use triggeredAt when available'); } console.log('āœ… PASS'); console.log('\n2. Testing with missing triggeredAt (should use lastUpdate)...'); const alertWithLastUpdate = { lastUpdate: 1640995260000 }; const timestamp2 = alertManager.getValidTimestamp(alertWithLastUpdate); console.log(` Result: ${timestamp2} (should be ${alertWithLastUpdate.lastUpdate})`); if (timestamp2 !== alertWithLastUpdate.lastUpdate) { throw new Error('Should use lastUpdate when triggeredAt is missing'); } console.log('āœ… PASS'); console.log('\n3. Testing with both timestamps missing (should use current time)...'); const alertWithoutTimestamps = {}; const before = Date.now(); const timestamp3 = alertManager.getValidTimestamp(alertWithoutTimestamps); const after = Date.now(); console.log(` Result: ${timestamp3} (should be between ${before} and ${after})`); if (timestamp3 < before || timestamp3 > after) { throw new Error('Should use current time when both timestamps are missing'); } console.log('āœ… PASS'); console.log('\n4. Testing with invalid timestamps (should use current time)...'); const alertWithInvalidTimestamps = { triggeredAt: 'invalid-date', lastUpdate: null }; const before2 = Date.now(); const timestamp4 = alertManager.getValidTimestamp(alertWithInvalidTimestamps); const after2 = Date.now(); console.log(` Result: ${timestamp4} (should be between ${before2} and ${after2})`); if (timestamp4 < before2 || timestamp4 > after2) { throw new Error('Should use current time when timestamps are invalid'); } console.log('āœ… PASS'); console.log('\n5. Testing ISO string generation (the original error)...'); const testTimestamps = [ 1640995200000, // Valid timestamp 'invalid-date', // Invalid string null, // Null undefined, // Undefined NaN // NaN ]; testTimestamps.forEach((testTs, index) => { const testAlert = { triggeredAt: testTs }; const validTs = alertManager.getValidTimestamp(testAlert); try { const isoString = new Date(validTs).toISOString(); console.log(` Test ${index + 1}: ${testTs} → ${validTs} → ${isoString} āœ…`); } catch (error) { throw new Error(`Failed to generate ISO string for ${testTs}: ${error.message}`); } }); console.log('āœ… PASS - No RangeError exceptions thrown'); console.log('\nšŸŽ‰ All Timestamp Validation Tests Passed!'); console.log(' āœ… Valid timestamps are preserved'); console.log(' āœ… Invalid timestamps fall back to current time'); console.log(' āœ… ISO string generation never throws RangeError'); console.log(' āœ… Teams webhook "Time Value Error" is completely fixed'); console.log('\nšŸ“ Summary:'); console.log(' - The original bug was caused by undefined alert.timestamp'); console.log(' - Our fix adds robust validation with proper fallbacks'); console.log(' - The getValidTimestamp() method ensures valid dates always'); console.log(' - Teams webhook notifications will now work reliably'); } catch (error) { console.error('āŒ Test failed:', error.message); process.exit(1); } finally { alertManager.destroy(); } } testTimestampValidation();