"""Tests for marketing_intelligence.evasion.behavior.BehaviorEmulator.""" import asyncio from unittest.mock import AsyncMock, MagicMock from marketing_intelligence.evasion.behavior import BehaviorEmulator class TestBehaviorEmulatorInit: def test_defaults(self) -> None: b = BehaviorEmulator() assert b.human is True assert b.delay_factor == 1.0 def test_human_false(self) -> None: assert BehaviorEmulator(human=False).human is False def test_custom_delay_factor(self) -> None: assert BehaviorEmulator(delay_factor=0.5).delay_factor == 0.5 def test_scroll_speed_normal(self) -> None: assert BehaviorEmulator(scroll_speed="normal")._scroll_base == 3000 def test_scroll_speed_slow(self) -> None: assert BehaviorEmulator(scroll_speed="slow")._scroll_base == 1500 def test_scroll_speed_fast(self) -> None: assert BehaviorEmulator(scroll_speed="fast")._scroll_base == 5000 def test_scroll_speed_unknown_defaults_to_3000(self) -> None: assert BehaviorEmulator(scroll_speed="turbo")._scroll_base == 3000 class TestHumanDelay: def test_non_human_completes_quickly(self) -> None: b = BehaviorEmulator(human=False) asyncio.run(b.human_delay(base=0.0, variance=0.0)) def test_human_with_zero_delay_factor_completes(self) -> None: b = BehaviorEmulator(human=True, delay_factor=0.0) asyncio.run(b.human_delay(base=0.0, variance=0.0)) def test_returns_coroutine(self) -> None: b = BehaviorEmulator(human=False) coro = b.human_delay(base=0.0, variance=0.0) assert asyncio.iscoroutine(coro) asyncio.run(coro) class TestScroll: def _make_page(self) -> MagicMock: page = MagicMock() page.mouse = MagicMock() page.mouse.wheel = AsyncMock() return page def test_non_human_calls_wheel_once(self) -> None: b = BehaviorEmulator(human=False) page = self._make_page() asyncio.run(b.scroll(page, distance=3000)) page.mouse.wheel.assert_called_once_with(0, 3000) def test_human_calls_wheel_multiple_times(self) -> None: b = BehaviorEmulator(human=True, delay_factor=0.001) page = self._make_page() asyncio.run(b.scroll(page, distance=3000)) assert page.mouse.wheel.call_count >= 2 def test_uses_scroll_base_when_distance_none(self) -> None: b = BehaviorEmulator(human=False, scroll_speed="slow") page = self._make_page() asyncio.run(b.scroll(page, distance=None)) args = page.mouse.wheel.call_args[0] assert args[0] == 0 assert args[1] == 1500 def test_explicit_distance_overrides_base(self) -> None: b = BehaviorEmulator(human=False, scroll_speed="slow") page = self._make_page() asyncio.run(b.scroll(page, distance=5000)) page.mouse.wheel.assert_called_once_with(0, 5000) class TestPauseForReading: def test_non_human_completes(self) -> None: b = BehaviorEmulator(human=False) asyncio.run(b.pause_for_reading()) def test_returns_coroutine(self) -> None: b = BehaviorEmulator(human=False) coro = b.pause_for_reading() assert asyncio.iscoroutine(coro) asyncio.run(coro)