← back to Dear Bubbe Nextjs
archived/tests/test-pricing-system.js
227 lines
#!/usr/bin/env node
/**
* Test script for Bubbe.ai pricing system
* Run with: node test-pricing-system.js
*/
const axios = require('axios');
const BASE_URL = 'http://localhost:3011';
const PRICING_URL = `${BASE_URL}/api/pricing`;
const CHAT_V2_URL = `${BASE_URL}/api/chat-v2`;
// Test results tracking
let passed = 0;
let failed = 0;
function log(message, type = 'info') {
const prefix = {
'info': '📝',
'success': '✅',
'error': '❌',
'test': '🧪'
}[type] || '📝';
console.log(`${prefix} ${message}`);
}
async function test(name, fn) {
try {
log(`Testing: ${name}`, 'test');
await fn();
passed++;
log(`PASSED: ${name}`, 'success');
} catch (error) {
failed++;
log(`FAILED: ${name}`, 'error');
console.error(' Error:', error.message);
}
console.log('');
}
// Test 1: Get all pricing plans
async function testGetPricingPlans() {
const response = await axios.get(PRICING_URL);
if (!response.data.plans) {
throw new Error('No plans returned');
}
if (response.data.plans.length !== 3) {
throw new Error(`Expected 3 plans, got ${response.data.plans.length}`);
}
const [basic, plus, max] = response.data.plans;
if (basic.pricePerMonth !== 0) {
throw new Error(`Basic plan should be free, but costs ${basic.pricePerMonth}`);
}
if (plus.pricePerMonth !== 18) {
throw new Error(`Plus plan should be $18, but costs ${plus.pricePerMonth}`);
}
if (max.pricePerMonth !== 36) {
throw new Error(`Max plan should be $36, but costs ${max.pricePerMonth}`);
}
log(' All plans have correct prices', 'info');
log(` Basic features: ${basic.features.length}`, 'info');
log(` Plus features: ${plus.features.length}`, 'info');
log(` Max features: ${max.features.length}`, 'info');
}
// Test 2: Feature recommendation
async function testFeatureRecommendation() {
// Test requesting voice notes (requires Max plan)
const response1 = await axios.post(PRICING_URL, {
action: 'recommend',
features: ['voice_notes']
});
if (response1.data.recommendedPlan.id !== 'max') {
throw new Error('Voice notes should require Max plan');
}
// Test requesting basic features (should be Basic plan)
const response2 = await axios.post(PRICING_URL, {
action: 'recommend',
features: ['advice_guilt', 'yiddish_sayings']
});
if (response2.data.recommendedPlan.id !== 'basic') {
throw new Error('Basic features should only require Basic plan');
}
// Test requesting Plus features
const response3 = await axios.post(PRICING_URL, {
action: 'recommend',
features: ['daily_reminders', 'cooking_tips']
});
if (response3.data.recommendedPlan.id !== 'plus') {
throw new Error('Daily reminders and cooking should require Plus plan');
}
log(' Recommendations work correctly for all tiers', 'info');
}
// Test 3: Plan upgrade
async function testPlanUpgrade() {
const userId = `test_user_${Date.now()}`;
// Upgrade to Plus
const response = await axios.post(PRICING_URL, {
action: 'upgrade',
plan: 'plus'
}, {
headers: { 'x-user-id': userId }
});
if (!response.data.success) {
throw new Error('Upgrade failed');
}
// Check the plan
const checkResponse = await axios.post(PRICING_URL, {
action: 'check'
}, {
headers: { 'x-user-id': userId }
});
if (checkResponse.data.id !== 'plus') {
throw new Error(`Expected Plus plan, got ${checkResponse.data.id}`);
}
log(` Successfully upgraded user to Plus plan`, 'info');
}
// Test 4: Feature blocking in chat
async function testFeatureBlocking() {
const userId = `test_basic_${Date.now()}`;
// Test as basic user asking for voice
const response = await axios.post(CHAT_V2_URL, {
message: "Can you send me a voice note?",
userId
}).catch(err => err.response);
if (!response.data.showUpgrade) {
throw new Error('Should show upgrade prompt for voice request on basic plan');
}
if (!response.data.blockedFeatures?.includes('voice_notes')) {
throw new Error('Should identify voice_notes as blocked feature');
}
log(' Feature blocking works correctly', 'info');
log(` Bubbe says: "${response.data.response.substring(0, 50)}..."`, 'info');
}
// Test 5: Bubbe responses
async function testBubbeResponses() {
const responses = [
"voice message",
"remind me daily",
"what's the recipe for",
"tell me family gossip",
"shabbat blessing"
];
for (const message of responses) {
const response = await axios.post(CHAT_V2_URL, {
message,
userId: `test_responses_${Date.now()}`
}).catch(err => err.response);
if (response.data.response && response.data.response.includes('$')) {
log(` Got pricing response for: "${message}"`, 'info');
}
}
}
// Main test runner
async function runTests() {
console.log('');
console.log('🧪 Starting Bubbe.ai Pricing System Tests');
console.log('=========================================');
console.log('');
// Check if server is running
try {
await axios.get(BASE_URL);
} catch (error) {
console.error('❌ Server not running on port 3011!');
console.error(' Please start the server first: npm run dev');
process.exit(1);
}
// Run all tests
await test('Get Pricing Plans', testGetPricingPlans);
await test('Feature Recommendation', testFeatureRecommendation);
await test('Plan Upgrade', testPlanUpgrade);
await test('Feature Blocking in Chat', testFeatureBlocking);
await test('Bubbe Responses', testBubbeResponses);
// Summary
console.log('=========================================');
console.log(`Results: ${passed} passed, ${failed} failed`);
if (failed === 0) {
console.log('✅ All tests passed! The pricing system works perfectly.');
console.log('');
console.log('Next steps:');
console.log('1. Integrate chat-v2 endpoint with existing chat logic');
console.log('2. Add payment processing (Stripe/PayPal)');
console.log('3. Add database persistence for user sessions');
console.log('4. Create pricing page UI component');
} else {
console.log('❌ Some tests failed. Please check the errors above.');
}
process.exit(failed === 0 ? 0 : 1);
}
// Run tests
runTests().catch(console.error);