Skip to main content
Glama

Hostaway MCP Server

test_financial.py10.4 kB
"""Unit tests for Financial models. Tests FinancialReport, RevenueBreakdown, ExpenseBreakdown models. Following TDD: These tests should FAIL until models are implemented. """ from datetime import date from decimal import Decimal import pytest from pydantic import ValidationError # Unit tests for financial models class TestFinancialModels: """Test suite for Financial-related Pydantic models.""" def test_financial_report_creation_with_all_fields(self) -> None: """Test that FinancialReport model can be created with all fields.""" # TODO: Import models once implemented # from src.models.financial import FinancialReport, RevenueBreakdown, ExpenseBreakdown, FinancialReportPeriod # # report = FinancialReport( # period_start=date(2025, 10, 1), # period_end=date(2025, 10, 31), # period_type=FinancialReportPeriod.MONTHLY, # listing_id=12345, # listing_name="Cozy Downtown Apartment", # revenue=RevenueBreakdown( # total_revenue=Decimal("12500.00"), # direct_bookings=Decimal("3000.00"), # airbnb=Decimal("6000.00"), # vrbo=Decimal("2500.00"), # booking_com=Decimal("1000.00"), # ), # expenses=ExpenseBreakdown( # total_expenses=Decimal("3250.00"), # cleaning=Decimal("1200.00"), # platform_fees=Decimal("1000.00"), # ), # net_income=Decimal("9250.00"), # total_bookings=15, # total_nights_booked=75, # average_daily_rate=Decimal("166.67"), # occupancy_rate=Decimal("80.65"), # ) # # assert report.period_start == date(2025, 10, 1) # assert report.period_type == FinancialReportPeriod.MONTHLY # assert report.revenue.total_revenue == Decimal("12500.00") # assert report.net_income == Decimal("9250.00") pass def test_revenue_breakdown_model(self) -> None: """Test RevenueBreakdown model for revenue tracking.""" # TODO: Import models once implemented # from src.models.financial import RevenueBreakdown # # revenue = RevenueBreakdown( # total_revenue=Decimal("12500.00"), # direct_bookings=Decimal("3000.00"), # airbnb=Decimal("6000.00"), # vrbo=Decimal("2500.00"), # booking_com=Decimal("1000.00"), # ) # # assert revenue.total_revenue == Decimal("12500.00") # assert revenue.airbnb == Decimal("6000.00") pass def test_expense_breakdown_model(self) -> None: """Test ExpenseBreakdown model for expense tracking.""" # TODO: Import models once implemented # from src.models.financial import ExpenseBreakdown # # expenses = ExpenseBreakdown( # total_expenses=Decimal("3250.00"), # cleaning=Decimal("1200.00"), # maintenance=Decimal("500.00"), # utilities=Decimal("300.00"), # platform_fees=Decimal("1000.00"), # supplies=Decimal("200.00"), # other=Decimal("50.00"), # ) # # assert expenses.total_expenses == Decimal("3250.00") # assert expenses.cleaning == Decimal("1200.00") pass def test_financial_report_period_enum(self) -> None: """Test FinancialReportPeriod enum values.""" # TODO: Import models once implemented # from src.models.financial import FinancialReportPeriod # # # Test enum values # assert FinancialReportPeriod.DAILY == "daily" # assert FinancialReportPeriod.WEEKLY == "weekly" # assert FinancialReportPeriod.MONTHLY == "monthly" # assert FinancialReportPeriod.QUARTERLY == "quarterly" # assert FinancialReportPeriod.YEARLY == "yearly" # assert FinancialReportPeriod.CUSTOM == "custom" pass def test_financial_report_profit_margin_property(self) -> None: """Test FinancialReport profit_margin property calculation.""" # TODO: Import models once implemented # from src.models.financial import FinancialReport, RevenueBreakdown, ExpenseBreakdown, FinancialReportPeriod # # report = FinancialReport( # period_start=date(2025, 10, 1), # period_end=date(2025, 10, 31), # period_type=FinancialReportPeriod.MONTHLY, # revenue=RevenueBreakdown(total_revenue=Decimal("10000.00")), # expenses=ExpenseBreakdown(total_expenses=Decimal("3000.00")), # net_income=Decimal("7000.00"), # total_bookings=10, # total_nights_booked=50, # average_daily_rate=Decimal("200.00"), # occupancy_rate=Decimal("75.00"), # ) # # # Profit margin = (7000 / 10000) * 100 = 70% # assert report.profit_margin == Decimal("70.00") pass def test_financial_report_profit_margin_zero_revenue(self) -> None: """Test profit_margin returns 0 when revenue is zero.""" # TODO: Import models once implemented # from src.models.financial import FinancialReport, RevenueBreakdown, ExpenseBreakdown, FinancialReportPeriod # # report = FinancialReport( # period_start=date(2025, 10, 1), # period_end=date(2025, 10, 31), # period_type=FinancialReportPeriod.MONTHLY, # revenue=RevenueBreakdown(total_revenue=Decimal("0.00")), # expenses=ExpenseBreakdown(total_expenses=Decimal("1000.00")), # net_income=Decimal("-1000.00"), # total_bookings=0, # total_nights_booked=0, # average_daily_rate=Decimal("0.00"), # occupancy_rate=Decimal("0.00"), # ) # # assert report.profit_margin == Decimal("0.00") pass def test_financial_report_validation_negative_amounts(self) -> None: """Test that FinancialReport validates non-negative amounts.""" # TODO: Import models once implemented # from src.models.financial import FinancialReport, RevenueBreakdown, ExpenseBreakdown, FinancialReportPeriod # # with pytest.raises(ValidationError) as exc_info: # FinancialReport( # period_start=date(2025, 10, 1), # period_end=date(2025, 10, 31), # period_type=FinancialReportPeriod.MONTHLY, # revenue=RevenueBreakdown(total_revenue=Decimal("-1000.00")), # Negative! # expenses=ExpenseBreakdown(total_expenses=Decimal("500.00")), # net_income=Decimal("-1500.00"), # total_bookings=0, # total_nights_booked=0, # average_daily_rate=Decimal("0.00"), # occupancy_rate=Decimal("0.00"), # ) # # assert "total_revenue" in str(exc_info.value) pass def test_financial_report_occupancy_rate_validation(self) -> None: """Test that occupancy_rate is validated between 0-100.""" # TODO: Import models once implemented # from src.models.financial import FinancialReport, RevenueBreakdown, ExpenseBreakdown, FinancialReportPeriod # # # Valid: 0-100 # report = FinancialReport( # period_start=date(2025, 10, 1), # period_end=date(2025, 10, 31), # period_type=FinancialReportPeriod.MONTHLY, # revenue=RevenueBreakdown(total_revenue=Decimal("5000.00")), # expenses=ExpenseBreakdown(total_expenses=Decimal("1000.00")), # net_income=Decimal("4000.00"), # total_bookings=5, # total_nights_booked=20, # average_daily_rate=Decimal("250.00"), # occupancy_rate=Decimal("95.50"), # ) # assert report.occupancy_rate == Decimal("95.50") # # # Invalid: > 100 # with pytest.raises(ValidationError) as exc_info: # FinancialReport( # period_start=date(2025, 10, 1), # period_end=date(2025, 10, 31), # period_type=FinancialReportPeriod.MONTHLY, # revenue=RevenueBreakdown(total_revenue=Decimal("5000.00")), # expenses=ExpenseBreakdown(total_expenses=Decimal("1000.00")), # net_income=Decimal("4000.00"), # total_bookings=5, # total_nights_booked=20, # average_daily_rate=Decimal("250.00"), # occupancy_rate=Decimal("105.00"), # > 100! # ) # assert "occupancy_rate" in str(exc_info.value) pass def test_revenue_breakdown_channel_defaults(self) -> None: """Test RevenueBreakdown has proper defaults for channels.""" # TODO: Import models once implemented # from src.models.financial import RevenueBreakdown # # revenue = RevenueBreakdown( # total_revenue=Decimal("5000.00"), # airbnb=Decimal("5000.00"), # Only airbnb, rest default to 0 # ) # # assert revenue.total_revenue == Decimal("5000.00") # assert revenue.airbnb == Decimal("5000.00") # assert revenue.direct_bookings == Decimal("0.00") # assert revenue.vrbo == Decimal("0.00") # assert revenue.booking_com == Decimal("0.00") # assert revenue.other == Decimal("0.00") pass def test_expense_breakdown_category_defaults(self) -> None: """Test ExpenseBreakdown has proper defaults for categories.""" # TODO: Import models once implemented # from src.models.financial import ExpenseBreakdown # # expenses = ExpenseBreakdown( # total_expenses=Decimal("1000.00"), # cleaning=Decimal("1000.00"), # Only cleaning, rest default to 0 # ) # # assert expenses.total_expenses == Decimal("1000.00") # assert expenses.cleaning == Decimal("1000.00") # assert expenses.maintenance == Decimal("0.00") # assert expenses.utilities == Decimal("0.00") # assert expenses.platform_fees == Decimal("0.00") # assert expenses.supplies == Decimal("0.00") # assert expenses.other == Decimal("0.00") pass

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/darrentmorgan/hostaway-mcp'

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