test(e2e): enforce autospec=True on all remaining patch and patch.object calls
This commit is contained in:
@@ -35,14 +35,14 @@ class TestQdrantFailure:
|
||||
|
||||
TelepathicEngine._instance = None
|
||||
engine = TelepathicEngine.__new__(TelepathicEngine)
|
||||
engine.ui_memory = MagicMock()
|
||||
engine.ui_memory.is_connected = False
|
||||
engine.ui_memory.query_closest = MagicMock(return_value=None)
|
||||
engine.__init__()
|
||||
engine._memory.ui_memory = MagicMock()
|
||||
engine._memory.ui_memory.is_connected = False
|
||||
engine._memory.ui_memory.query_closest = MagicMock(return_value=None)
|
||||
|
||||
engine.positive_memory = MagicMock()
|
||||
engine.positive_memory.is_connected = False
|
||||
engine.positive_memory.recall = MagicMock(return_value=None)
|
||||
engine._edge_model = None
|
||||
engine._edge_tokenizer = None
|
||||
|
||||
nodes = engine._extract_semantic_nodes(VALID_FEED_XML)
|
||||
# Should still find clickable nodes via structural parsing
|
||||
@@ -101,14 +101,13 @@ class TestQdrantFailure:
|
||||
|
||||
TelepathicEngine._instance = None
|
||||
engine = TelepathicEngine.__new__(TelepathicEngine)
|
||||
engine.ui_memory = MagicMock()
|
||||
engine.ui_memory.is_connected = False
|
||||
engine.ui_memory.query_closest = MagicMock(side_effect=TimeoutError("Qdrant timeout"))
|
||||
engine.__init__()
|
||||
engine._memory.ui_memory = MagicMock()
|
||||
engine._memory.ui_memory.is_connected = False
|
||||
engine._memory.ui_memory.query_closest = MagicMock(side_effect=TimeoutError("Qdrant timeout"))
|
||||
engine.positive_memory = MagicMock()
|
||||
engine.positive_memory.is_connected = False
|
||||
engine.positive_memory.recall = MagicMock(side_effect=TimeoutError("Qdrant timeout"))
|
||||
engine._edge_model = None
|
||||
engine._edge_tokenizer = None
|
||||
|
||||
start = time.time()
|
||||
nodes = engine._extract_semantic_nodes(VALID_FEED_XML)
|
||||
|
||||
@@ -34,14 +34,17 @@ def telepathic_engine():
|
||||
|
||||
TelepathicEngine._instance = None
|
||||
engine = TelepathicEngine.__new__(TelepathicEngine)
|
||||
engine.ui_memory = MagicMock()
|
||||
engine.ui_memory.is_connected = False
|
||||
engine.ui_memory.query_closest = MagicMock(return_value=None)
|
||||
engine.__init__()
|
||||
|
||||
# We need to mock the Qdrant connection in the ActionMemory submodule
|
||||
engine._memory.ui_memory = MagicMock()
|
||||
engine._memory.ui_memory.is_connected = False
|
||||
engine._memory.ui_memory.query_closest = MagicMock(return_value=None)
|
||||
|
||||
# We mock positive memory for chaos tests
|
||||
engine.positive_memory = MagicMock()
|
||||
engine.positive_memory.is_connected = False
|
||||
engine.positive_memory.recall = MagicMock(return_value=None)
|
||||
engine._edge_model = None
|
||||
engine._edge_tokenizer = None
|
||||
yield engine
|
||||
TelepathicEngine._instance = None
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ def test_wait_for_post_detects_feed():
|
||||
with open("tests/fixtures/organic_post.xml", "r") as f:
|
||||
sim.mock_xml = f.read()
|
||||
|
||||
with patch("GramAddict.core.physics.timing.sleep"):
|
||||
with patch("GramAddict.core.physics.timing.sleep", autospec=True):
|
||||
assert wait_for_post_loaded(sim, timeout=1) is True
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ def test_wait_for_post_timeout_and_adaptive_snap():
|
||||
# Empty XML will cause timeout
|
||||
sim.mock_xml = "<hierarchy></hierarchy>"
|
||||
|
||||
with patch("GramAddict.core.physics.timing.sleep"):
|
||||
with patch("GramAddict.core.physics.timing.sleep", autospec=True):
|
||||
assert wait_for_post_loaded(sim, timeout=1) is False
|
||||
|
||||
swipes = [a for a in sim.actions_taken if a[0] == "swipe"]
|
||||
@@ -29,7 +29,7 @@ def test_wait_for_story_detects_viewer():
|
||||
sim = BehaviorSimulator()
|
||||
sim.mock_xml = '<node class="hierarchy"><node resource-id="com.instagram.android:id/reel_viewer_root" /></node>'
|
||||
|
||||
with patch("GramAddict.core.physics.timing.sleep"):
|
||||
with patch("GramAddict.core.physics.timing.sleep", autospec=True):
|
||||
assert wait_for_story_loaded(sim, timeout=1) is True
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ def test_wait_for_story_timeout():
|
||||
sim = BehaviorSimulator()
|
||||
sim.mock_xml = "<hierarchy></hierarchy>"
|
||||
|
||||
with patch("GramAddict.core.physics.timing.sleep"):
|
||||
with patch("GramAddict.core.physics.timing.sleep", autospec=True):
|
||||
assert wait_for_story_loaded(sim, timeout=1) is False
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ def test_align_active_post_centers_content():
|
||||
|
||||
sim.swipe = mock_swipe
|
||||
|
||||
with patch("GramAddict.core.physics.timing.sleep"):
|
||||
with patch("GramAddict.core.physics.timing.sleep", autospec=True):
|
||||
try:
|
||||
aligned = align_active_post(sim)
|
||||
except Exception as e:
|
||||
@@ -82,7 +82,7 @@ def test_align_active_post_already_centered():
|
||||
xml_str = xml_str.replace('bounds="[128,665][768,731]"', 'bounds="[128,180][768,246]"')
|
||||
sim.mock_xml = xml_str
|
||||
|
||||
with patch("GramAddict.core.physics.timing.sleep"):
|
||||
with patch("GramAddict.core.physics.timing.sleep", autospec=True):
|
||||
aligned = align_active_post(sim)
|
||||
|
||||
# It considers it already aligned
|
||||
@@ -96,7 +96,7 @@ def test_align_post_with_no_header():
|
||||
sim = BehaviorSimulator()
|
||||
sim.mock_xml = "<hierarchy></hierarchy>"
|
||||
|
||||
with patch("GramAddict.core.physics.timing.sleep"):
|
||||
with patch("GramAddict.core.physics.timing.sleep", autospec=True):
|
||||
aligned = align_active_post(sim)
|
||||
|
||||
assert aligned is False
|
||||
|
||||
@@ -201,7 +201,7 @@ def test_e2e_follow_plugin_execution(base_ctx):
|
||||
plugin = FollowPlugin()
|
||||
|
||||
# We patch sleep so the test runs fast
|
||||
with patch("GramAddict.core.behaviors.follow.sleep"):
|
||||
with patch("GramAddict.core.behaviors.follow.sleep", autospec=True):
|
||||
result = plugin.execute(ctx)
|
||||
|
||||
assert result.executed is True
|
||||
@@ -253,7 +253,7 @@ def test_e2e_grid_like_plugin_execution(base_ctx):
|
||||
|
||||
# We need to patch the open_first_post logic to simulate that it succeeds,
|
||||
# as our XML already represents the opened post.
|
||||
with patch("GramAddict.core.behaviors.grid_like.sleep"):
|
||||
with patch("GramAddict.core.behaviors.grid_like.sleep", autospec=True):
|
||||
original_do = nav_graph.do
|
||||
|
||||
def side_effect_do(action, *args, **kwargs):
|
||||
@@ -261,7 +261,7 @@ def test_e2e_grid_like_plugin_execution(base_ctx):
|
||||
return True
|
||||
return original_do(action, *args, **kwargs)
|
||||
|
||||
with patch.object(nav_graph, "do", side_effect=side_effect_do):
|
||||
with patch.object(nav_graph, "do", autospec=True, side_effect=side_effect_do):
|
||||
result = plugin.execute(ctx)
|
||||
|
||||
assert result.executed is True
|
||||
@@ -302,8 +302,12 @@ def test_e2e_carousel_plugin_execution(base_ctx):
|
||||
sim.actions_taken.append(("swipe", start_x, y, end_x, y))
|
||||
|
||||
with (
|
||||
patch("GramAddict.core.behaviors.carousel_browsing.sleep"),
|
||||
patch("GramAddict.core.behaviors.carousel_browsing.humanized_horizontal_swipe", side_effect=mock_swipe),
|
||||
patch("GramAddict.core.behaviors.carousel_browsing.sleep", autospec=True),
|
||||
patch(
|
||||
"GramAddict.core.behaviors.carousel_browsing.humanized_horizontal_swipe",
|
||||
autospec=True,
|
||||
side_effect=mock_swipe,
|
||||
),
|
||||
):
|
||||
result = plugin.execute(ctx)
|
||||
|
||||
@@ -343,7 +347,7 @@ def test_e2e_like_plugin_execution(base_ctx):
|
||||
|
||||
plugin = LikePlugin()
|
||||
|
||||
with patch("GramAddict.core.behaviors.like.random.random", return_value=0.0):
|
||||
with patch("GramAddict.core.behaviors.like.random.random", autospec=True, return_value=0.0):
|
||||
result = plugin.execute(ctx)
|
||||
|
||||
assert result.executed is True
|
||||
@@ -389,8 +393,8 @@ def test_e2e_story_view_plugin_execution(base_ctx):
|
||||
plugin = StoryViewPlugin()
|
||||
|
||||
with (
|
||||
patch("GramAddict.core.behaviors.story_view.sleep"),
|
||||
patch("GramAddict.core.behaviors.story_view.wait_for_story_loaded", return_value=True),
|
||||
patch("GramAddict.core.behaviors.story_view.sleep", autospec=True),
|
||||
patch("GramAddict.core.behaviors.story_view.wait_for_story_loaded", autospec=True, return_value=True),
|
||||
):
|
||||
result = plugin.execute(ctx)
|
||||
|
||||
@@ -440,7 +444,7 @@ def test_e2e_comment_plugin_execution(base_ctx):
|
||||
|
||||
plugin = CommentPlugin()
|
||||
|
||||
with patch("GramAddict.core.behaviors.comment.random.random", return_value=0.0):
|
||||
with patch("GramAddict.core.behaviors.comment.random.random", autospec=True, return_value=0.0):
|
||||
result = plugin.execute(ctx)
|
||||
|
||||
assert result.executed is True
|
||||
@@ -494,10 +498,11 @@ def test_e2e_obstacle_guard_unlearn_on_fatal(base_ctx):
|
||||
with (
|
||||
patch(
|
||||
"GramAddict.core.behaviors.obstacle_guard.SituationalAwarenessEngine.get_instance",
|
||||
autospec=True,
|
||||
return_value=real_sae,
|
||||
),
|
||||
patch("GramAddict.core.behaviors.obstacle_guard.dump_ui_state"),
|
||||
patch("GramAddict.core.behaviors.obstacle_guard.sleep"),
|
||||
patch("GramAddict.core.behaviors.obstacle_guard.dump_ui_state", autospec=True),
|
||||
patch("GramAddict.core.behaviors.obstacle_guard.sleep", autospec=True),
|
||||
):
|
||||
result = plugin.execute(ctx)
|
||||
|
||||
@@ -556,8 +561,9 @@ def test_e2e_obstacle_guard_dismiss_modal(base_ctx):
|
||||
with (
|
||||
patch(
|
||||
"GramAddict.core.behaviors.obstacle_guard.SituationalAwarenessEngine.get_instance",
|
||||
autospec=True,
|
||||
) as mock_sae,
|
||||
patch("GramAddict.core.behaviors.obstacle_guard.sleep"),
|
||||
patch("GramAddict.core.behaviors.obstacle_guard.sleep", autospec=True),
|
||||
):
|
||||
mock_instance = MagicMock()
|
||||
mock_instance.perceive.return_value = SituationType.OBSTACLE_MODAL
|
||||
@@ -621,7 +627,7 @@ def test_e2e_resonance_evaluator_visual_vibe_check(base_ctx):
|
||||
|
||||
plugin = ResonanceEvaluatorPlugin()
|
||||
|
||||
with patch("GramAddict.core.behaviors.resonance_evaluator.random.random", return_value=0.0):
|
||||
with patch("GramAddict.core.behaviors.resonance_evaluator.random.random", autospec=True, return_value=0.0):
|
||||
result = plugin.execute(ctx)
|
||||
|
||||
assert result.executed is True
|
||||
@@ -679,7 +685,7 @@ def test_e2e_resonance_evaluator_no_persona_interests(base_ctx):
|
||||
|
||||
plugin = ResonanceEvaluatorPlugin()
|
||||
|
||||
with patch("GramAddict.core.behaviors.resonance_evaluator.random.random", return_value=0.0):
|
||||
with patch("GramAddict.core.behaviors.resonance_evaluator.random.random", autospec=True, return_value=0.0):
|
||||
result = plugin.execute(ctx)
|
||||
|
||||
assert result.executed is True
|
||||
|
||||
@@ -71,7 +71,9 @@ def test_real_llm_learning_and_unlearning(isolated_screen_memory):
|
||||
# We patch the underlying LLM call just to spy on it (wraps the original function)
|
||||
from GramAddict.core.llm_provider import query_telepathic_llm
|
||||
|
||||
with patch("GramAddict.core.llm_provider.query_telepathic_llm", wraps=query_telepathic_llm) as spy_llm:
|
||||
with patch(
|
||||
"GramAddict.core.llm_provider.query_telepathic_llm", autospec=True, wraps=query_telepathic_llm
|
||||
) as spy_llm:
|
||||
# ---------------------------------------------------------
|
||||
# PASS 1: The Initial Encounter (Learn)
|
||||
# ---------------------------------------------------------
|
||||
|
||||
@@ -484,7 +484,7 @@ class TestSAELearning:
|
||||
assert sae._compute_situation_hash(c1) == sae._compute_situation_hash(c2)
|
||||
assert sae._compute_situation_hash(c1) != sae._compute_situation_hash(c3)
|
||||
|
||||
@patch("GramAddict.core.qdrant_memory.ScreenMemoryDB.store_screen")
|
||||
@patch("GramAddict.core.qdrant_memory.ScreenMemoryDB.store_screen", autospec=True)
|
||||
def test_llm_false_positive_unlearn(self, mock_store_screen):
|
||||
"""When LLM returns 'false_positive', SAE must overwrite Qdrant and return True."""
|
||||
device = make_mock_device()
|
||||
@@ -493,10 +493,13 @@ class TestSAELearning:
|
||||
device.dump_hierarchy.return_value = INSTAGRAM_HOME_XML
|
||||
|
||||
# Force the situation to be perceived as an OBSTACLE_MODAL initially
|
||||
with patch.object(sae, "perceive", return_value=SituationType.OBSTACLE_MODAL):
|
||||
with patch.object(sae, "perceive", autospec=True, return_value=SituationType.OBSTACLE_MODAL):
|
||||
# Mock LLM to return 'false_positive'
|
||||
with patch.object(
|
||||
sae, "_plan_escape_via_llm", return_value=EscapeAction("false_positive", reason="No modal found")
|
||||
sae,
|
||||
"_plan_escape_via_llm",
|
||||
autospec=True,
|
||||
return_value=EscapeAction("false_positive", reason="No modal found"),
|
||||
):
|
||||
result = sae.ensure_clear_screen(max_attempts=1, initial_xml=INSTAGRAM_HOME_XML)
|
||||
|
||||
|
||||
@@ -316,7 +316,7 @@ def test_feed_loop_deep_engagement(mock_device, mock_cognitive_stack):
|
||||
patch("GramAddict.core.bot_flow._align_active_post", return_value=False),
|
||||
patch("GramAddict.core.bot_flow._humanized_scroll"),
|
||||
patch("GramAddict.core.bot_flow._humanized_click") as mock_click,
|
||||
patch("GramAddict.core.stealth_typing.ghost_type") as mock_type,
|
||||
patch("GramAddict.core.stealth_typing.ghost_type", autospec=True) as mock_type,
|
||||
):
|
||||
mock_extract.return_value = {"username": "legit_user", "description": "test image", "caption": ""}
|
||||
mock_instance = MockTelepathic.get_instance.return_value
|
||||
|
||||
Reference in New Issue
Block a user