"""Integration tests for report generation pipeline.""" import calendar import json from datetime import datetime import pytest BASE_TS = 1704067200 @pytest.mark.integration class TestReportGenerationPipeline: """Test report generation end-to-end.""" def test_generates_monthly_reports(self, populated_db_with_history, reports_env): """Should generate monthly reports for available data.""" from meshmon.html import render_report_page from meshmon.reports import aggregate_monthly, format_monthly_txt, get_available_periods # Get available periods periods = get_available_periods("repeater") assert periods # Get the current month (should have data) year, month = periods[-1] month_name = calendar.month_name[month] # Aggregate monthly data agg = aggregate_monthly("repeater", year, month) assert agg is not None assert agg.year == year assert agg.month == month assert agg.role == "repeater" assert agg.daily assert agg.summary["bat"].count > 0 assert agg.summary["bat"].min_value is not None assert agg.summary["nb_recv"].total is not None assert agg.summary["nb_recv"].count > 0 # Generate TXT report from meshmon.reports import LocationInfo location = LocationInfo( name="Test Location", lat=52.0, lon=4.0, elev=10.0, ) txt_report = format_monthly_txt(agg, "Test Repeater", location) assert txt_report is not None assert len(txt_report) > 0 assert f"MONTHLY MESHCORE REPORT for {month_name} {year}" in txt_report assert "NODE: Test Repeater" in txt_report assert "NAME: Test Location" in txt_report # Generate HTML report html_report = render_report_page(agg, "Test Repeater", "monthly") assert html_report is not None assert " 0 # Get the current year year = periods[-1][0] # Aggregate yearly data agg = aggregate_yearly("repeater", year) assert agg is not None assert agg.year == year assert agg.role == "repeater" assert agg.monthly assert agg.summary["bat"].count > 0 assert agg.summary["nb_recv"].total is not None # Generate TXT report from meshmon.reports import LocationInfo location = LocationInfo( name="Test Location", lat=52.0, lon=4.0, elev=10.0, ) txt_report = format_yearly_txt(agg, "Test Repeater", location) assert txt_report is not None assert len(txt_report) > 0 assert f"YEARLY MESHCORE REPORT for {year}" in txt_report assert "NODE: Test Repeater" in txt_report # Generate HTML report html_report = render_report_page(agg, "Test Repeater", "yearly") assert html_report is not None assert " 0 assert len((report_dir / "report.txt").read_text()) > 0 assert len((report_dir / "report.json").read_text()) > 0 assert f"{month_name} {year}" in (report_dir / "index.html").read_text() assert "NODE: Test Repeater" in (report_dir / "report.txt").read_text() parsed_json = json.loads((report_dir / "report.json").read_text()) assert parsed_json["report_type"] == "monthly" assert parsed_json["year"] == year assert parsed_json["month"] == month @pytest.mark.integration class TestReportsIndex: """Test reports index page generation.""" def test_generates_reports_index(self, populated_db_with_history, reports_env): """Should generate reports index with all available periods.""" from meshmon.html import render_reports_index from meshmon.reports import get_available_periods out_dir = reports_env["out_dir"] # Build sections data (mimicking render_reports.py) sections = [] latest_periods: dict[str, tuple[int, int]] = {} for role in ["repeater", "companion"]: periods = get_available_periods(role) if not periods: sections.append({"role": role, "years": []}) continue latest_periods[role] = periods[-1] years_data = {} for year, month in periods: if year not in years_data: years_data[year] = [] years_data[year].append( { "month": month, "name": calendar.month_name[month], } ) years = [] for year in sorted(years_data.keys(), reverse=True): years.append( { "year": year, "months": sorted(years_data[year], key=lambda m: m["month"]), } ) sections.append({"role": role, "years": years}) # Render index html = render_reports_index(sections) assert html is not None assert "