/** * Test Auto-Eligibility Filtering in /api/activePromos Endpoint * * Tests that the activePromos endpoint: * 1. Requires authentication * 2. Automatically filters promos by customer eligibility * 3. Returns only eligible promos based on subscription history * * Prerequisites: * - MongoDB running with test promos configured * - Valid test user with authentication token * - Subscription history cache populated */ const path = require('path'); // Parse --env argument (default: ./environment.env) const args = process.argv.slice(2); let envFile = './environment.env'; for (let i = 0; i < args.length; i++) { if (args[i] === '--env' && args[i + 1]) { envFile = args[i + 1]; i++; } } // Load environment before requiring any modules const envPath = path.resolve(process.cwd(), envFile); require('dotenv').config({ path: envPath }); const axios = require('axios'); const assert = require('assert'); // Test configuration const BASE_URL = process.env.APP_URL || 'https://localhost:4200'; const API_URL = BASE_URL.replace('4200', '4100'); // Server runs on 4100 // Test user credentials (update with valid test user) const TEST_USER_EMAIL = 'trungduyhoang@gmail.com'; const TEST_USER_PASSWORD = 'secret'; let authToken = null; let testUserId = null; // HTTPS agent to accept self-signed certificates const https = require('https'); const httpsAgent = new https.Agent({ rejectUnauthorized: false }); /** * Step 1: Login to get authentication token */ async function login() { try { console.log('\n--- Step 1: Login ---'); const response = await axios.post(`${API_URL}/api/users/login`, { username: TEST_USER_EMAIL, password: TEST_USER_PASSWORD }, { httpsAgent }); authToken = response.data.token; testUserId = response.data.user?._id; console.log('✅ Login successful'); console.log(` User ID: ${testUserId}`); console.log(` Token: ${authToken.substring(0, 20)}...`); return true; } catch (error) { console.error('❌ Login failed:', error.response?.data || error.message); console.error('\n⚠️ Update TEST_USER_EMAIL and TEST_USER_PASSWORD in script with valid credentials'); return false; } } /** * Step 2: Test authenticated access to /api/activePromos */ async function testAuthenticatedAccess() { try { console.log('\n--- Step 2: Test Authenticated Access ---'); const response = await axios.get(`${API_URL}/api/activePromos`, { headers: { 'Authorization': `Bearer ${authToken}` }, httpsAgent }); console.log('✅ Authenticated request successful'); console.log(` Promos returned: ${response.data.promos.length}`); console.log(` Current mode: ${response.data.currentMode.mode}`); console.log(` Mode active: ${response.data.currentMode.isActive}`); // Verify response structure assert(Array.isArray(response.data.promos), 'promos should be an array'); assert(response.data.currentMode, 'currentMode should be present'); assert(['enabled', 'disabled'].includes(response.data.currentMode.mode), 'currentMode.mode should be "enabled" or "disabled"'); return response.data; } catch (error) { console.error('❌ Authenticated request failed:', error.response?.data || error.message); throw error; } } /** * Step 3: Test unauthenticated access (should fail) */ async function testUnauthenticatedAccess() { try { console.log('\n--- Step 3: Test Unauthenticated Access (Should Fail) ---'); await axios.get(`${API_URL}/api/activePromos`, { httpsAgent }); console.error('❌ UNEXPECTED: Unauthenticated request succeeded (should have failed)'); return false; } catch (error) { if (error.response?.status === 401) { console.log('✅ Unauthenticated request correctly rejected (401)'); return true; } console.error('❌ Unexpected error:', error.response?.data || error.message); return false; } } /** * Step 4: Verify eligibility filtering */ async function verifyEligibilityFiltering(promosData) { console.log('\n--- Step 4: Verify Eligibility Filtering ---'); const promos = promosData.promos; // All returned promos should have eligibility field const allHaveEligibility = promos.every(p => p.eligibility); assert(allHaveEligibility, 'All promos should have eligibility field'); console.log('✅ All promos have eligibility field'); // Check eligibility values const eligibilityTypes = [...new Set(promos.map(p => p.eligibility))]; console.log(` Eligibility types in results: ${eligibilityTypes.join(', ')}`); // All eligibility values should be valid const validEligibility = promos.every(p => ['all', 'new_only', 'renew_only'].includes(p.eligibility)); assert(validEligibility, 'All eligibility values should be valid'); console.log('✅ All eligibility values are valid'); // Log details console.log('\n Promo Details:'); promos.forEach((p, i) => { console.log(` ${i + 1}. ${p.name}`); console.log(` Type: ${p.type}, PriceKey: ${p.priceKey}`); console.log(` Eligibility: ${p.eligibility}`); console.log(` Priority: ${p.priority}`); if (p.durationInMonths) { console.log(` Duration: ${p.durationInMonths} months`); } if (p.validUntil) { console.log(` Valid Until: ${p.validUntil}`); } }); return true; } /** * Step 5: Test PROMO_MODE disabled */ async function testDisabledMode() { console.log('\n--- Step 5: Test PROMO_MODE Disabled (Manual) ---'); console.log('⚠️ To test disabled mode:'); console.log(' 1. Set PROMO_MODE=disabled in environment.env'); console.log(' 2. Restart server'); console.log(' 3. Run this test again'); console.log(' 4. Expected: promos array should be empty, mode should be "disabled"'); console.log(' 5. Remember to set PROMO_MODE=enabled after testing'); } /** * Main test execution */ async function runTests() { console.log('='.repeat(70)); console.log('TEST: Active Promos Auto-Eligibility Filtering'); console.log('='.repeat(70)); console.log(`API URL: ${API_URL}`); console.log(`Test User: ${TEST_USER_EMAIL}`); try { // Step 1: Login const loginSuccess = await login(); if (!loginSuccess) { process.exit(1); } // Step 2: Test authenticated access const promosData = await testAuthenticatedAccess(); // Step 3: Test unauthenticated access await testUnauthenticatedAccess(); // Step 4: Verify eligibility filtering await verifyEligibilityFiltering(promosData); // Step 5: Manual test for disabled mode await testDisabledMode(); console.log('\n' + '='.repeat(70)); console.log('✅ ALL TESTS PASSED'); console.log('='.repeat(70)); } catch (error) { console.error('\n' + '='.repeat(70)); console.error('❌ TEST FAILED'); console.error('='.repeat(70)); console.error(error); process.exit(1); } } // Run tests runTests();