Skip to main content
Glama
sigaihealth

RealVest Real Estate MCP Server

property-management.test.js20.9 kB
import { test } from 'node:test'; import assert from 'node:assert'; import { PropertyManagementCalculator } from '../src/calculators/property-management.js'; test('PropertyManagementCalculator - Basic Property Management Analysis', () => { const calc = new PropertyManagementCalculator(); const result = calc.calculate({ property_details: { property_type: 'duplex', total_units: 2, property_value: 400000, monthly_rent_per_unit: 1800, property_age_years: 15, property_condition: 'good', location_grade: 'B+', tenant_quality: 'good' }, management_options: { self_management: { owner_hourly_rate: 60, estimated_hours_per_month: 8, owner_experience_level: 'intermediate' }, professional_management: { management_fee_percentage: 8, setup_fee: 500, leasing_fee: 1800, maintenance_markup: 15 } } }); // Test structure assert(result.property_overview, 'Should have property overview'); assert(result.self_management, 'Should have self management analysis'); assert(result.professional_management, 'Should have professional management analysis'); assert(result.cost_benefit_analysis, 'Should have cost benefit analysis'); assert(result.recommendations, 'Should have recommendations'); // Test property overview const overview = result.property_overview; assert(overview.property_type === 'duplex', 'Should preserve property type'); assert(overview.total_units === 2, 'Should preserve unit count'); assert(overview.monthly_gross_rent === 3600, 'Should calculate gross rent (2 * $1800)'); assert(overview.annual_gross_rent === 43200, 'Should calculate annual gross rent'); // Test self management analysis const selfMgmt = result.self_management; assert(typeof selfMgmt.monthly_cost === 'number', 'Should calculate monthly self-management cost'); assert(typeof selfMgmt.annual_cost === 'number', 'Should calculate annual self-management cost'); assert(selfMgmt.time_investment.estimated_hours_per_month > 0, 'Should estimate time investment'); assert(selfMgmt.suitability_score >= 0 && selfMgmt.suitability_score <= 100, 'Should have valid suitability score'); // Test professional management analysis const profMgmt = result.professional_management; assert(profMgmt.monthly_cost === 288, 'Should calculate 8% of $3600 monthly rent'); assert(typeof profMgmt.annual_cost === 'number', 'Should calculate annual professional cost'); assert(profMgmt.fee_structure.management_fee_percentage === 8, 'Should preserve management fee'); assert(profMgmt.suitability_score >= 0 && profMgmt.suitability_score <= 100, 'Should have valid suitability score'); // Test cost benefit analysis const costBenefit = result.cost_benefit_analysis; assert(typeof costBenefit.monthly_cost_difference === 'number', 'Should calculate monthly cost difference'); assert(typeof costBenefit.annual_cost_difference === 'number', 'Should calculate annual cost difference'); assert(costBenefit.breakeven_analysis, 'Should include breakeven analysis'); }); test('PropertyManagementCalculator - Single Family Property Analysis', () => { const calc = new PropertyManagementCalculator(); const result = calc.calculate({ property_details: { property_type: 'single_family', total_units: 1, property_value: 300000, monthly_rent_per_unit: 2200, property_age_years: 8, property_condition: 'excellent' }, management_options: { self_management: { owner_hourly_rate: 75, owner_experience_level: 'beginner' } } }); const selfMgmt = result.self_management; // Beginner should have experience multiplier of 1.5 assert(selfMgmt.efficiency_metrics.experience_adjustment_factor === 1.5, 'Should apply beginner experience multiplier'); // Single family should have higher self-management suitability assert(selfMgmt.suitability_score > 50, 'Single family should have reasonable self-management suitability'); // Should identify beginner challenges const beginnerChallenge = selfMgmt.challenges.find(c => c.challenge === 'Learning Curve'); assert(beginnerChallenge, 'Should identify learning curve challenge for beginners'); assert(beginnerChallenge.severity === 'High', 'Learning curve should be high severity for beginners'); }); test('PropertyManagementCalculator - Large Multi-Family Analysis', () => { const calc = new PropertyManagementCalculator(); const result = calc.calculate({ property_details: { property_type: 'large_multifamily', total_units: 25, property_value: 2500000, monthly_rent_per_unit: 1500, property_condition: 'fair', tenant_quality: 'average' }, management_options: { professional_management: { management_fee_percentage: 5, services_included: [ 'tenant_screening', 'rent_collection', 'maintenance_coordination', 'property_inspections', 'financial_reporting', 'legal_compliance', 'marketing', 'lease_preparation', '24_7_emergency' ] } } }); const profMgmt = result.professional_management; const selfMgmt = result.self_management; // Large multifamily should favor professional management assert(profMgmt.suitability_score > selfMgmt.suitability_score, 'Large multifamily should favor professional management'); // Should calculate significant monthly rent assert(result.property_overview.monthly_gross_rent === 37500, 'Should calculate $37,500 monthly gross rent'); // Professional management fee should be lower percentage for large properties assert(profMgmt.fee_structure.management_fee_percentage === 5, 'Should use lower fee percentage for large multifamily'); // Should identify scale management challenges for self-management const scaleChallenge = selfMgmt.challenges.find(c => c.challenge === 'Scale Management'); assert(scaleChallenge, 'Should identify scale management challenge'); }); test('PropertyManagementCalculator - Comparison Analysis', () => { const calc = new PropertyManagementCalculator(); const result = calc.calculate({ property_details: { property_type: 'triplex', total_units: 3, property_value: 450000, monthly_rent_per_unit: 1600 }, analysis_options: { comparison_analysis: true } }); const comparison = result.comparison_analysis; assert(comparison, 'Should include comparison analysis when requested'); assert(comparison.cost_comparison, 'Should provide cost comparison'); assert(comparison.efficiency_comparison, 'Should provide efficiency comparison'); assert(comparison.suitability_comparison, 'Should provide suitability comparison'); assert(typeof comparison.cost_comparison.monthly_difference === 'number', 'Should calculate monthly difference'); assert(typeof comparison.cost_comparison.cost_ratio === 'number', 'Should calculate cost ratio'); assert(['Self Management', 'Professional Management'].includes(comparison.efficiency_comparison.efficiency_advantage), 'Should identify efficiency advantage'); assert(['Self Management', 'Professional Management'].includes(comparison.suitability_comparison.recommended_approach), 'Should recommend an approach'); }); test('PropertyManagementCalculator - Scenario Modeling', () => { const calc = new PropertyManagementCalculator(); const result = calc.calculate({ property_details: { property_type: 'fourplex', total_units: 4, property_value: 600000, monthly_rent_per_unit: 1400 }, analysis_options: { scenario_modeling: true } }); const scenarios = result.scenario_modeling; assert(scenarios, 'Should include scenario modeling when requested'); assert(Array.isArray(scenarios), 'Scenario modeling should be an array'); assert(scenarios.length >= 3, 'Should provide multiple scenarios'); scenarios.forEach(scenario => { assert(scenario.name, 'Each scenario should have a name'); assert(scenario.impact_description, 'Each scenario should have impact description'); assert(typeof scenario.adjusted_monthly_income === 'number', 'Should calculate adjusted monthly income'); assert(typeof scenario.adjusted_annual_income === 'number', 'Should calculate adjusted annual income'); assert(scenario.management_impact, 'Should describe management impact'); }); // Should include high and low vacancy scenarios const highVacancyScenario = scenarios.find(s => s.name === 'High Vacancy Scenario'); const lowVacancyScenario = scenarios.find(s => s.name === 'Low Vacancy Scenario'); assert(highVacancyScenario, 'Should include high vacancy scenario'); assert(lowVacancyScenario, 'Should include low vacancy scenario'); }); test('PropertyManagementCalculator - Efficiency Optimization', () => { const calc = new PropertyManagementCalculator(); const result = calc.calculate({ property_details: { property_type: 'small_multifamily', total_units: 6, property_value: 720000, monthly_rent_per_unit: 1300 }, analysis_options: { efficiency_optimization: true } }); const optimization = result.efficiency_optimization; assert(optimization, 'Should include efficiency optimization when requested'); assert(Array.isArray(optimization.optimization_opportunities), 'Should provide optimization opportunities'); assert(optimization.optimization_opportunities.length > 0, 'Should have multiple optimization opportunities'); assert(typeof optimization.total_potential_annual_savings === 'number', 'Should calculate total potential savings'); assert(typeof optimization.total_implementation_cost === 'number', 'Should calculate implementation cost'); optimization.optimization_opportunities.forEach(opp => { assert(opp.category, 'Should have category'); assert(opp.recommendation, 'Should have recommendation'); assert(typeof opp.estimated_savings === 'number', 'Should have estimated savings'); assert(typeof opp.implementation_cost === 'number', 'Should have implementation cost'); assert(typeof opp.payback_months === 'number', 'Should have payback period'); }); // Should include technology optimization const techOpp = optimization.optimization_opportunities.find(o => o.category === 'Technology'); assert(techOpp, 'Should include technology optimization opportunity'); }); test('PropertyManagementCalculator - Risk Assessment', () => { const calc = new PropertyManagementCalculator(); const result = calc.calculate({ property_details: { property_type: 'commercial', total_units: 15, property_value: 1800000, monthly_rent_per_unit: 2200, property_age_years: 35, property_condition: 'poor' }, market_conditions: { vacancy_rate: 12, market_competition_level: 'high' }, analysis_options: { risk_assessment: true } }); const risk = result.risk_assessment; assert(risk, 'Should include risk assessment when requested'); assert(Array.isArray(risk.identified_risks), 'Should identify specific risks'); assert(risk.identified_risks.length > 0, 'Should identify multiple risks'); assert(['High', 'Medium', 'Low'].includes(risk.overall_risk_level), 'Should assign valid risk level'); assert(Array.isArray(risk.risk_mitigation_priority), 'Should provide risk mitigation priorities'); // Should identify market risk due to high vacancy const marketRisk = risk.identified_risks.find(r => r.category === 'Market Risk'); assert(marketRisk, 'Should identify market risk with high vacancy rate'); assert(marketRisk.severity === 'High', 'High vacancy should be high severity risk'); // Should identify property risk due to age and condition const propertyRisk = risk.identified_risks.find(r => r.category === 'Property Risk'); assert(propertyRisk, 'Should identify property risk with old, poor condition property'); // Should identify management risk due to large size const managementRisk = risk.identified_risks.find(r => r.category === 'Management Risk'); assert(managementRisk, 'Should identify management risk with 15+ units'); }); test('PropertyManagementCalculator - ROI Analysis', () => { const calc = new PropertyManagementCalculator(); const result = calc.calculate({ property_details: { property_type: 'duplex', total_units: 2, property_value: 350000, monthly_rent_per_unit: 1700 }, analysis_options: { roi_analysis: true } }); const roi = result.roi_analysis; assert(roi, 'Should include ROI analysis when requested'); assert(roi.self_management, 'Should calculate self-management ROI'); assert(roi.professional_management, 'Should calculate professional management ROI'); assert(typeof roi.roi_difference === 'number', 'Should calculate ROI difference'); assert(['Self Management', 'Professional Management'].includes(roi.better_roi_option), 'Should identify better ROI option'); const selfROI = roi.self_management; const profROI = roi.professional_management; assert(typeof selfROI.annual_net_income === 'number', 'Should calculate self-management net income'); assert(typeof selfROI.roi_percentage === 'number', 'Should calculate self-management ROI percentage'); assert(typeof selfROI.cash_on_cash_return === 'number', 'Should calculate cash-on-cash return'); assert(typeof profROI.annual_net_income === 'number', 'Should calculate professional management net income'); assert(typeof profROI.roi_percentage === 'number', 'Should calculate professional management ROI percentage'); assert(typeof profROI.cash_on_cash_return === 'number', 'Should calculate cash-on-cash return'); }); test('PropertyManagementCalculator - Recommendations Generation', () => { const calc = new PropertyManagementCalculator(); const result = calc.calculate({ property_details: { property_type: 'small_multifamily', total_units: 8, property_value: 800000, monthly_rent_per_unit: 1500 }, management_options: { self_management: { owner_experience_level: 'experienced' } } }); const recommendations = result.recommendations; assert(recommendations, 'Should provide recommendations'); assert(Array.isArray(recommendations.recommendations), 'Should have recommendations array'); assert(recommendations.recommendations.length > 0, 'Should have multiple recommendations'); assert(recommendations.implementation_timeline, 'Should provide implementation timeline'); assert(Array.isArray(recommendations.success_metrics), 'Should provide success metrics'); // Should have primary recommendation const primaryRec = recommendations.recommendations.find(r => r.category === 'Primary Recommendation'); assert(primaryRec, 'Should include primary recommendation'); assert(primaryRec.priority === 'High', 'Primary recommendation should be high priority'); // Should provide timeline phases const timeline = recommendations.implementation_timeline; assert(Array.isArray(timeline), 'Implementation timeline should be array'); assert(timeline.length >= 2, 'Should have multiple timeline phases'); timeline.forEach(phase => { assert(phase.phase, 'Each phase should have name'); assert(Array.isArray(phase.tasks), 'Each phase should have tasks'); }); }); test('PropertyManagementCalculator - Expert Owner Scenario', () => { const calc = new PropertyManagementCalculator(); const result = calc.calculate({ property_details: { property_type: 'triplex', total_units: 3, property_value: 480000, monthly_rent_per_unit: 1650 }, management_options: { self_management: { owner_hourly_rate: 100, owner_experience_level: 'expert' } } }); const selfMgmt = result.self_management; // Expert should have experience multiplier of 0.8 (more efficient) assert(selfMgmt.efficiency_metrics.experience_adjustment_factor === 0.8, 'Should apply expert experience multiplier'); // Expert should have high self-management suitability assert(selfMgmt.suitability_score > 70, 'Expert should have high self-management suitability'); // Should not include learning curve challenge for expert const learningCurveChallenge = selfMgmt.challenges.find(c => c.challenge === 'Learning Curve'); assert(!learningCurveChallenge, 'Should not include learning curve challenge for expert'); }); test('PropertyManagementCalculator - Mixed Use Property', () => { const calc = new PropertyManagementCalculator(); const result = calc.calculate({ property_details: { property_type: 'mixed_use', total_units: 12, property_value: 1200000, monthly_rent_per_unit: 1800, property_condition: 'good', location_grade: 'A-' } }); const overview = result.property_overview; assert(overview.monthly_gross_rent === 21600, 'Should calculate correct gross rent for 12 units'); // Mixed use should have moderate suitability for both approaches const selfMgmt = result.self_management; const profMgmt = result.professional_management; assert(selfMgmt.suitability_score < profMgmt.suitability_score, 'Mixed use with 12 units should favor professional management'); // Should use 6% management fee for mixed use assert(profMgmt.fee_structure.management_fee_percentage === 6, 'Should use 6% management fee for mixed use'); }); test('PropertyManagementCalculator - Commercial Property Analysis', () => { const calc = new PropertyManagementCalculator(); const result = calc.calculate({ property_details: { property_type: 'commercial', total_units: 8, property_value: 1600000, monthly_rent_per_unit: 2800 } }); const profMgmt = result.professional_management; // Commercial should use 4% management fee assert(profMgmt.fee_structure.management_fee_percentage === 4, 'Should use 4% management fee for commercial'); // Commercial should strongly favor professional management assert(profMgmt.suitability_score > 80, 'Commercial should have high professional management suitability'); }); test('PropertyManagementCalculator - Schema Validation', () => { const calc = new PropertyManagementCalculator(); const schema = calc.getSchema(); assert(schema.type === 'object', 'Schema should be an object'); assert(schema.properties.property_details, 'Should have property_details property'); assert(schema.properties.management_options, 'Should have management_options property'); assert(schema.properties.operational_expenses, 'Should have operational_expenses property'); assert(schema.properties.market_conditions, 'Should have market_conditions property'); assert(schema.properties.analysis_options, 'Should have analysis_options property'); assert(schema.required.includes('property_details'), 'property_details should be required'); // Test property details schema const propertyDetails = schema.properties.property_details; assert(propertyDetails.properties.property_type, 'Should define property_type'); assert(propertyDetails.properties.total_units, 'Should define total_units'); assert(propertyDetails.properties.property_value, 'Should define property_value'); assert(propertyDetails.properties.monthly_rent_per_unit, 'Should define monthly_rent_per_unit'); // Test property type enum const propertyTypeEnum = propertyDetails.properties.property_type.enum; assert(propertyTypeEnum.includes('single_family'), 'Should include single_family'); assert(propertyTypeEnum.includes('duplex'), 'Should include duplex'); assert(propertyTypeEnum.includes('large_multifamily'), 'Should include large_multifamily'); assert(propertyTypeEnum.includes('commercial'), 'Should include commercial'); // Test management options schema const managementOptions = schema.properties.management_options; assert(managementOptions.properties.self_management, 'Should define self_management options'); assert(managementOptions.properties.professional_management, 'Should define professional_management options'); const selfMgmtSchema = managementOptions.properties.self_management; assert(selfMgmtSchema.properties.owner_hourly_rate, 'Should define owner_hourly_rate'); assert(selfMgmtSchema.properties.owner_experience_level, 'Should define owner_experience_level'); const profMgmtSchema = managementOptions.properties.professional_management; assert(profMgmtSchema.properties.management_fee_percentage, 'Should define management_fee_percentage'); assert(profMgmtSchema.properties.services_included, 'Should define services_included'); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sigaihealth/realvestmcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server