"""Blocking policy: when it is on, and what is on the list.""" from __future__ import annotations from app.services import blocker_service, pomodoro, settings_service def test_disabled_blocker_blocks_nothing(session, settings): pomodoro.start(session, settings, kind="work") policy = blocker_service.policy(session, settings) assert policy["active"] is False and policy["domains"] == [] def test_during_work_mode_follows_the_timer(session, settings): settings.blocker.enabled = True settings.blocker.blocked_domains = ["youtube.com"] settings_service.save_settings(session, settings) assert blocker_service.policy(session, settings)["active"] is False pomodoro.start(session, settings, kind="work") policy = blocker_service.policy(session, settings) assert policy["active"] is True assert "www.youtube.com" in policy["domains"] pomodoro.complete(session, settings, auto_next=False) assert blocker_service.policy(session, settings)["active"] is False def test_breaks_do_not_block_unless_asked(session, settings): settings.blocker.enabled = True settings_service.save_settings(session, settings) pomodoro.start(session, settings, kind="short_break") assert blocker_service.policy(session, settings)["active"] is False settings.blocker.block_during_breaks = True settings_service.save_settings(session, settings) assert blocker_service.policy(session, settings)["active"] is True def test_always_mode_ignores_the_timer(session, settings): settings.blocker.enabled = True settings.blocker.mode = "always" settings_service.save_settings(session, settings) assert blocker_service.policy(session, settings)["active"] is True def test_allowlist_wins_over_the_blocklist(session, settings): settings.blocker.blocked_domains = ["youtube.com"] settings.blocker.allowed_domains = ["m.youtube.com"] hosts = blocker_service.expand_domains(settings) assert "youtube.com" in hosts assert "m.youtube.com" not in hosts def test_events_are_grouped_for_the_report(session, settings): for _ in range(3): blocker_service.record_event(session, settings, kind="domain", target="YouTube.com") blocker_service.record_event(session, settings, kind="app", target="steam") summary = blocker_service.events_for_day(session, settings) assert summary["total"] == 4 assert summary["by_target"][0] == {"target": "youtube.com", "count": 3} def test_masked_subdomains_are_expanded(session, settings): """A hosts file has no wildcards, so `*.x` has to become real names.""" settings.blocker.blocked_domains = ["*.google.com"] settings.blocker.subdomain_expansions = ["www", "mail"] hosts = blocker_service.expand_domains(settings) assert hosts == ["google.com", "www.google.com", "mail.google.com"] def test_allow_masks_carve_holes_in_block_masks(session, settings): settings.blocker.blocked_domains = ["*.google.com", "reddit.com"] settings.blocker.subdomain_expansions = ["www", "docs"] settings.blocker.allowed_domains = ["docs.*", "m.reddit.com"] hosts = blocker_service.expand_domains(settings) assert "docs.google.com" not in hosts assert "m.reddit.com" not in hosts assert "www.google.com" in hosts and "reddit.com" in hosts def test_patterns_a_hosts_file_cannot_express_are_reported(session, settings): settings.blocker.blocked_domains = ["*gram*", "youtube.com", "*.x.com"] assert blocker_service.unexpandable_masks(settings) == ["*gram*"] hosts = blocker_service.expand_domains(settings) assert "youtube.com" in hosts and "x.com" in hosts def test_app_masks_are_passed_through_untouched(session, settings): """Process matching happens on the desktop, where globs work directly.""" settings.blocker.enabled = True settings.blocker.mode = "always" settings.blocker.blocked_apps = ["steam*", "*discord*"] settings_service.save_settings(session, settings) policy = blocker_service.policy(session, settings) assert policy["apps"] == ["steam*", "*discord*"]