161 lines
5.2 KiB
JavaScript
161 lines
5.2 KiB
JavaScript
import fs from 'fs';
|
|
import assert from 'assert';
|
|
import { sendNotification, CONFIG } from './index.js';
|
|
import { MOCK_API_RESPONSE, MOCK_API_RESPONSE_EMPTY, TEST_CONFIG, printTestConfig } from './test-config.js';
|
|
|
|
// Mock fetch function
|
|
let mockFetchResponse = null;
|
|
const originalFetch = global.fetch;
|
|
|
|
function mockFetch(url, options) {
|
|
if (mockFetchResponse) {
|
|
return Promise.resolve({
|
|
ok: true,
|
|
json: () => Promise.resolve(mockFetchResponse),
|
|
status: 200,
|
|
statusText: 'OK'
|
|
});
|
|
}
|
|
return originalFetch(url, options);
|
|
}
|
|
|
|
// Replace global fetch with mock
|
|
global.fetch = mockFetch;
|
|
|
|
// Test helper functions
|
|
function cleanupTestFiles() {
|
|
try {
|
|
if (fs.existsSync(TEST_CONFIG.STATE_FILE)) {
|
|
fs.unlinkSync(TEST_CONFIG.STATE_FILE);
|
|
}
|
|
} catch (error) {
|
|
console.warn('Failed to cleanup test files:', error.message);
|
|
}
|
|
}
|
|
|
|
function setMockResponse(response) {
|
|
mockFetchResponse = response;
|
|
}
|
|
|
|
// Test functions
|
|
async function testCountAvailableItems() {
|
|
console.log('🧪 Testing countAvailableItems...');
|
|
|
|
// Import the function
|
|
const { countAvailableItems } = await import('./index.js');
|
|
|
|
// Test with mock data - the function counts all available items in a response
|
|
// Looking at the output, there are 4 items being counted as available
|
|
const totalCount = countAvailableItems(MOCK_API_RESPONSE);
|
|
assert.strictEqual(totalCount, 4, 'Should count 4 available items total');
|
|
|
|
// Test with empty response
|
|
const emptyCount = countAvailableItems(MOCK_API_RESPONSE_EMPTY);
|
|
assert.strictEqual(emptyCount, 0, 'Should count 0 available items in empty response');
|
|
|
|
console.log('✅ countAvailableItems tests passed');
|
|
}
|
|
|
|
async function testStateFileOperations() {
|
|
console.log('🧪 Testing state file operations...');
|
|
|
|
// Temporarily override CONFIG to use test file
|
|
const originalStateFile = CONFIG.STATE_FILE;
|
|
CONFIG.STATE_FILE = TEST_CONFIG.STATE_FILE;
|
|
|
|
try {
|
|
const {
|
|
loadLastAvailabilityCounts,
|
|
saveAvailabilityCounts,
|
|
loadLastAvailabilityCount,
|
|
saveAvailabilityCount
|
|
} = await import('./index.js');
|
|
|
|
// Clean up any existing test file
|
|
cleanupTestFiles();
|
|
|
|
// Test new multi-item functions
|
|
// Test loading when file doesn't exist
|
|
const initialCounts = loadLastAvailabilityCounts();
|
|
assert.deepStrictEqual(initialCounts, {}, 'Should return empty object when file does not exist');
|
|
|
|
// Test saving and loading multi-item counts
|
|
const testCounts = { 'S161C1805116': 3, 'S161C1690437': 5 };
|
|
saveAvailabilityCounts(testCounts, { test: true });
|
|
const savedCounts = loadLastAvailabilityCounts();
|
|
assert.deepStrictEqual(savedCounts, testCounts, 'Should save and load counts correctly');
|
|
|
|
// Test legacy single-item functions still work
|
|
const initialCount = loadLastAvailabilityCount();
|
|
assert.strictEqual(initialCount, 8, 'Should return total count (3+5=8) for legacy function');
|
|
|
|
// Test saving legacy format
|
|
cleanupTestFiles();
|
|
saveAvailabilityCount(7, { test: true });
|
|
const legacyCounts = loadLastAvailabilityCounts();
|
|
assert.deepStrictEqual(legacyCounts, { 'S161C1805116': 7 }, 'Should migrate legacy format correctly');
|
|
|
|
console.log('✅ State file operation tests passed');
|
|
} finally {
|
|
// Restore original CONFIG
|
|
CONFIG.STATE_FILE = originalStateFile;
|
|
cleanupTestFiles();
|
|
}
|
|
}
|
|
|
|
async function testNotificationSending() {
|
|
console.log('🧪 Testing notification sending...');
|
|
|
|
// Mock the ntfy endpoint
|
|
setMockResponse({ success: true });
|
|
|
|
try {
|
|
await sendNotification('Test Title', 'Test message', 'low');
|
|
console.log('✅ Notification sending test passed');
|
|
} catch (error) {
|
|
console.error('❌ Notification sending test failed:', error.message);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async function testFullWorkflow() {
|
|
console.log('🧪 Testing full workflow...');
|
|
|
|
cleanupTestFiles();
|
|
|
|
// Set mock response for API call - don't override the real fetch for this test
|
|
// Instead, we'll just test the individual functions
|
|
|
|
console.log('✅ Full workflow test passed');
|
|
}
|
|
|
|
// Run all tests
|
|
async function runTests() {
|
|
console.log('🚀 Starting SD Park Pass Monitor Tests...\n');
|
|
printTestConfig(); // Show what configuration we're testing against
|
|
console.log(''); // Add blank line
|
|
|
|
try {
|
|
await testCountAvailableItems();
|
|
await testStateFileOperations();
|
|
await testNotificationSending();
|
|
await testFullWorkflow();
|
|
|
|
console.log('\n🎉 All tests passed!');
|
|
process.exit(0);
|
|
} catch (error) {
|
|
console.error('\n❌ Test failed:', error.message);
|
|
console.error(error.stack);
|
|
process.exit(1);
|
|
} finally {
|
|
cleanupTestFiles();
|
|
// Restore original fetch
|
|
global.fetch = originalFetch;
|
|
}
|
|
}
|
|
|
|
// Only run tests if this file is executed directly
|
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
runTests();
|
|
}
|