# retoor from datetime import date import pytest from devplacepy.database import ( AGE_BANDS, MATURITY_TARGETS, REPORTABLE_TARGETS, REPORT_REASONS, SOFT_DELETE_TABLES, UNREPORTABLE_TABLES, age_band_for, years_between, ) from devplacepy.database.moderation import MODERATION_TABLES GUIDELINE_REASONS = ( "hate", "violence", "weapons", "sexual", "religious", "misinformation", "exploitative", ) def test_every_visible_soft_delete_table_is_reportable(): reportable_tables = set(REPORTABLE_TARGETS.values()) excluded = set(UNREPORTABLE_TABLES) | set(MODERATION_TABLES) unclassified = [ table for table in SOFT_DELETE_TABLES if table not in reportable_tables and table not in excluded ] assert unclassified == [] def test_exclusion_list_only_names_real_soft_delete_tables(): unknown = [table for table in UNREPORTABLE_TABLES if table not in SOFT_DELETE_TABLES] assert unknown == [] def test_registry_tables_are_unique_and_maturity_is_a_subset(): assert len(set(REPORTABLE_TARGETS.values())) == len(REPORTABLE_TARGETS) assert MATURITY_TARGETS <= set(REPORTABLE_TARGETS) def test_report_reasons_cover_every_guideline_category(): for reason in GUIDELINE_REASONS: assert reason in REPORT_REASONS assert REPORT_REASONS["intellectual_property"] assert REPORT_REASONS["other"] def test_every_registry_target_resolves_to_a_url(local_db): from devplacepy.database import resolve_object_url for target_type in REPORTABLE_TARGETS: url = resolve_object_url(target_type, "missing-uid") assert url.startswith("/") def test_resolve_object_url_points_at_the_owning_surface(local_db): from devplacepy.database import get_table, resolve_object_url get_table("users").insert( {"uid": "mod-user-1", "username": "mod_user_1", "deleted_at": None} ) get_table("messages").insert( { "uid": "mod-msg-1", "sender_uid": "mod-user-1", "receiver_uid": "mod-user-2", "content": "hello", } ) try: assert resolve_object_url("user", "mod-user-1") == "/profile/mod_user_1" assert ( resolve_object_url("message", "mod-msg-1") == "/messages?with_uid=mod-user-1" ) assert resolve_object_url("devii_output", "anything") == "/devii" finally: get_table("users").delete(uid="mod-user-1") get_table("messages").delete(uid="mod-msg-1") @pytest.mark.parametrize( "age,expected", [ (0, "under_min"), (12, "under_min"), (13, "13_15"), (15, "13_15"), (16, "16_17"), (17, "16_17"), (18, "adult"), (120, "adult"), ], ) def test_age_band_boundaries(age, expected): assert age_band_for(age) == expected def test_age_band_is_monotonic_across_the_whole_domain(): order = {band: index for index, band in enumerate(AGE_BANDS)} previous = -1 for age in range(0, 150): current = order[age_band_for(age)] assert current >= previous previous = current def test_years_between_handles_leap_days_and_exact_boundaries(): assert years_between(date(2000, 2, 29), date(2018, 2, 28)) == 17 assert years_between(date(2000, 2, 29), date(2018, 3, 1)) == 18 assert years_between(date(2008, 1, 1), date(2026, 1, 1)) == 18 assert years_between(date(2008, 1, 2), date(2026, 1, 1)) == 17 def test_years_between_never_exceeds_the_calendar_difference(): born = date(2005, 6, 15) for offset in range(0, 4000, 7): today = date.fromordinal(born.toordinal() + offset) years = years_between(born, today) assert 0 <= years <= today.year - born.year