135 lines
4.5 KiB
JavaScript
135 lines
4.5 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Test Active Promos Endpoint
|
|
*
|
|
* Verifies that /api/activePromos returns V2 enhancement fields:
|
|
* - priority
|
|
* - eligibility
|
|
* - durationInMonths
|
|
* - chainable
|
|
*
|
|
* NOTE (v3.0): This test queries the database directly and does NOT test
|
|
* the actual HTTP endpoint. For v3.0 authentication and eligibility filtering,
|
|
* use test_active_promos_eligibility.js instead.
|
|
*/
|
|
|
|
const path = require('path');
|
|
|
|
// Parse --env argument
|
|
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
|
|
const envPath = path.resolve(process.cwd(), envFile);
|
|
require('dotenv').config({ path: envPath });
|
|
|
|
const connect = require('../helpers/db/connect');
|
|
const Settings = require('../model/setting');
|
|
const moment = require('moment');
|
|
|
|
console.log('=== Active Promos Endpoint Test ===\n');
|
|
|
|
async function testActivePromosEndpoint() {
|
|
try {
|
|
await connect(false);
|
|
console.log('1. Fetching active promos from database...');
|
|
|
|
const settings = await Settings.findOne({ userId: null }).lean();
|
|
const now = moment.utc();
|
|
|
|
const activePromos = (settings?.subscriptionPromos || [])
|
|
.filter(p => {
|
|
if (!p.enabled) return false;
|
|
|
|
const validDate = p.validUntil;
|
|
|
|
// Include if:
|
|
// 1. Has validUntil in the future, OR
|
|
// 2. Is a repeating coupon (has durationInMonths) without validUntil (self-expiring)
|
|
if (validDate) {
|
|
return moment.utc(validDate).isAfter(now);
|
|
} else {
|
|
return p.durationInMonths && p.durationInMonths > 0;
|
|
}
|
|
});
|
|
|
|
console.log(` Total promos in database: ${settings?.subscriptionPromos?.length || 0}`);
|
|
console.log(` Active promos: ${activePromos.length}`);
|
|
console.log('');
|
|
|
|
if (activePromos.length === 0) {
|
|
console.log('⚠️ No active promos found. Create a test promo with:');
|
|
console.log(' - enabled: true');
|
|
console.log(' - validUntil: future date');
|
|
console.log(' - priority, eligibility, durationInMonths, chainable fields');
|
|
return 0;
|
|
}
|
|
|
|
console.log('2. Simulating endpoint response format...');
|
|
const responsePromos = activePromos.map(p => ({
|
|
type: p.type,
|
|
priceKey: p.priceKey,
|
|
validUntil: p.validUntil,
|
|
name: p.name,
|
|
nameKey: p.nameKey,
|
|
descriptionKey: p.descriptionKey,
|
|
discountType: p.discountType,
|
|
discountValue: p.discountValue,
|
|
// V2 Enhancement fields
|
|
priority: p.priority || 0,
|
|
eligibility: p.eligibility || 'all',
|
|
durationInMonths: p.durationInMonths,
|
|
chainable: p.chainable || false
|
|
}));
|
|
|
|
console.log('');
|
|
console.log('3. Verifying V2 fields are included:');
|
|
|
|
let allHaveV2Fields = true;
|
|
responsePromos.forEach((promo, idx) => {
|
|
console.log(`\n Promo ${idx + 1}: ${promo.name || 'Unnamed'}`);
|
|
console.log(` - priority: ${promo.priority} ${typeof promo.priority === 'number' ? '✓' : '✗'}`);
|
|
console.log(` - eligibility: ${promo.eligibility} ${promo.eligibility ? '✓' : '✗'}`);
|
|
console.log(` - durationInMonths: ${promo.durationInMonths || 'N/A'} ${promo.durationInMonths ? '✓' : '(optional)'}`);
|
|
console.log(` - chainable: ${promo.chainable} ${typeof promo.chainable === 'boolean' ? '✓' : '✗'}`);
|
|
|
|
if (typeof promo.priority !== 'number' || !promo.eligibility || typeof promo.chainable !== 'boolean') {
|
|
allHaveV2Fields = false;
|
|
}
|
|
});
|
|
|
|
console.log('');
|
|
console.log('4. Security check - couponId should NOT be included:');
|
|
const hasCouponId = responsePromos.some(p => p.couponId !== undefined);
|
|
console.log(` couponId excluded: ${!hasCouponId ? '✓ YES' : '✗ NO (SECURITY ISSUE!)'}`);
|
|
|
|
console.log('');
|
|
console.log('=== Test Summary ===');
|
|
if (allHaveV2Fields && !hasCouponId) {
|
|
console.log('✓ All tests passed!');
|
|
console.log('Active promos endpoint correctly includes V2 fields without exposing couponId.');
|
|
return 0;
|
|
} else {
|
|
console.log('✗ Test failed!');
|
|
if (!allHaveV2Fields) console.log(' - Not all promos have required V2 fields');
|
|
if (hasCouponId) console.log(' - couponId is exposed (security issue)');
|
|
return 1;
|
|
}
|
|
|
|
} catch (err) {
|
|
console.error('ERROR:', err.message);
|
|
return 1;
|
|
} finally {
|
|
process.exit(0);
|
|
}
|
|
}
|
|
|
|
testActivePromosEndpoint().then(code => process.exit(code));
|