import datetime import io from openpyxl import load_workbook from backend.actions.dsar_report import build_excel, profile_rows from backend.dtos import DsarResult, ExportRecord, Profile, Subscription def _make_profile(**kwargs) -> Profile: defaults = dict( profile_id=None, crm_id=None, email="fan@example.com", first_name="Jane", last_name="Doe", phone_number="555", country_code="US", city="NYC", region="NY", address="1 Main St", zip_code="10001", date_of_birth=datetime.date(1990, 6, 15), birthday="Jun 15", deleted=False, deleted_at=None, ) return Profile(**{**defaults, **kwargs}) def _make_result(profile=None, subscriptions=None, exports=None) -> DsarResult: return DsarResult( profile=profile or _make_profile(), subscriptions=subscriptions or [], exports=exports or [], ) # --- profile_rows --- def test_profile_rows_omits_none_fields(): profile = _make_profile(city=None, region=None) rows = profile_rows(profile) assert "City" not in rows assert "State" not in rows def test_profile_rows_omits_empty_full_name_when_both_names_none(): profile = _make_profile(first_name=None, last_name=None) rows = profile_rows(profile) assert "Full Name" not in rows def test_profile_rows_full_name_concatenates_parts(): profile = _make_profile(first_name="Jane", last_name="Doe") rows = profile_rows(profile) assert rows["Full Name"] == "Jane Doe" def test_profile_rows_full_name_handles_missing_last_name(): profile = _make_profile(first_name="Jane", last_name=None) rows = profile_rows(profile) assert rows["Full Name"] == "Jane" def test_profile_rows_age_calculated_from_date_of_birth(): dob = datetime.date(1990, 1, 1) profile = _make_profile(date_of_birth=dob) rows = profile_rows(profile) today = datetime.date.today() expected_age = today.year - 1990 - ((today.month, today.day) < (1, 1)) assert rows["Age"] == str(expected_age) def test_profile_rows_omits_age_when_dob_missing(): profile = _make_profile(date_of_birth=None) rows = profile_rows(profile) assert "Age" not in rows assert "Birthdate" not in rows def test_profile_rows_includes_all_present_fields(): profile = _make_profile() rows = profile_rows(profile) for field in [ "First Name", "Last Name", "Full Name", "Mobile Phone", "Address 1", "City", "State", "Country / Region", "Postal Code", "Birthday", "Birthdate", "Age", ]: assert field in rows, f"Expected field '{field}' to be present" # --- build_excel --- def _load_wb(result: DsarResult): return load_workbook(io.BytesIO(build_excel(result))) def test_build_excel_has_three_sheets(): wb = _load_wb(_make_result()) assert wb.sheetnames == ["Export History", "PII", "Fan Active Subscriptions"] def test_build_excel_pii_sheet_omits_blank_fields(): profile = _make_profile(city=None, region=None, address=None) wb = _load_wb(_make_result(profile=profile)) field_col = [row[0].value for row in wb["PII"].iter_rows(min_row=2)] assert "City" not in field_col assert "State" not in field_col assert "Address 1" not in field_col def test_build_excel_pii_sheet_includes_deletion_date_for_deleted_fan(): profile = _make_profile(deleted=True, deleted_at=datetime.datetime(2024, 1, 15)) wb = _load_wb(_make_result(profile=profile)) field_col = [row[0].value for row in wb["PII"].iter_rows(min_row=2)] assert "Deletion Date" in field_col def test_build_excel_exports_sheet_has_header_row(): export = ExportRecord( export_date=datetime.datetime(2024, 6, 1), business_reason="promo", recipient_email=None, recipient_name="John", export_type="campaign", exported_by="John", fan_first_name="Jane", fan_last_name="Doe", fan_email="fan@example.com", source="Salesforce", ) wb = _load_wb(_make_result(exports=[export])) header = [cell.value for cell in wb["Export History"][1]] assert "Export Date" in header assert "Business Reason" in header assert "Destination" in header assert "Exported By" in header assert "Fan Email" in header assert "Source" in header def test_build_excel_subscriptions_sheet_has_header_row(): sub = Subscription( created_at=datetime.datetime(2024, 5, 1), artist_name="My Artist" ) wb = _load_wb(_make_result(subscriptions=[sub])) header = [cell.value for cell in wb["Fan Active Subscriptions"][1]] assert "Created Date" in header assert "Artist" in header def test_build_excel_empty_sections_show_placeholder(): result = DsarResult(profile=None, subscriptions=[], exports=[]) wb = _load_wb(result) assert wb["Export History"].cell(1, 1).value == "No export records found." assert wb["PII"].cell(1, 1).value == "No profile found." assert ( wb["Fan Active Subscriptions"].cell(1, 1).value == "No active subscriptions found." )