agmission/Development/server/tests/test_active_promos_eligibility.js

225 lines
6.9 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 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();