- Separated obstacle detection from feed marker validation - Prevented blind BACK button presses when markers are missing mid-scroll - Added TDD verification for feed navigation stability - Cleaned up debug artifacts and temporary test output
94 lines
3.5 KiB
Python
94 lines
3.5 KiB
Python
import pytest
|
|
import logging
|
|
import os
|
|
from unittest.mock import MagicMock
|
|
MagicMock.app_id = "com.instagram.android"
|
|
MagicMock._get_current_app = MagicMock(return_value="com.instagram.android")
|
|
|
|
class MockArgs:
|
|
def __init__(self, **kwargs):
|
|
for k, v in kwargs.items():
|
|
setattr(self, k, v)
|
|
|
|
class MockConfigs:
|
|
def __init__(self, args):
|
|
self.args = args
|
|
|
|
from unittest.mock import create_autospec, MagicMock
|
|
from GramAddict.core.device_facade import DeviceFacade
|
|
from GramAddict.core.telepathic_engine import TelepathicEngine
|
|
|
|
def create_mock_device():
|
|
mock = create_autospec(DeviceFacade, instance=True)
|
|
mock.app_id = "com.instagram.android"
|
|
mock.device_id = "test_device"
|
|
|
|
mock.info = {"displayWidth": 1080, "displayHeight": 2400}
|
|
mock.get_info.return_value = {"displayWidth": 1080, "displayHeight": 2400}
|
|
mock.cm_to_pixels.side_effect = lambda cm: int(cm * 10)
|
|
import uuid
|
|
mock.dump_hierarchy.side_effect = lambda: f"<hierarchy><node resource-id=\"com.instagram.android:id/row_comment_imageview\" bounds=\"[10,10][20,20]\" content-desc=\"Story\" text=\"following\" /><node resource-id=\"com.instagram.android:id/button_like\" bounds=\"[50,50][60,60]\" /><node resource-id=\"com.instagram.android:id/reel_viewer\" /><node sid=\"{uuid.uuid4()}\" /></hierarchy>"
|
|
|
|
return mock
|
|
|
|
def create_mock_telepathic_engine():
|
|
mock = create_autospec(TelepathicEngine, instance=True)
|
|
mock.find_best_node.return_value = {"x": 500, "y": 500, "confidence": 0.9}
|
|
mock.evaluate_profile_vibe.return_value = {"quality_score": 8, "matches_niche": True, "reason": "Mocked positive vibe"}
|
|
mock.evaluate_grid_visuals.return_value = [0.9] * 6
|
|
mock._extract_semantic_nodes.return_value = [{"x": 500, "y": 500, "semantic_string": "dummy node"}]
|
|
return mock
|
|
|
|
@pytest.fixture
|
|
def mock_logger():
|
|
return logging.getLogger("test")
|
|
|
|
@pytest.fixture
|
|
def device():
|
|
return create_mock_device()
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def reset_singletons():
|
|
"""Ensure all core engine singletons are fresh for each test."""
|
|
from GramAddict.core.telepathic_engine import TelepathicEngine
|
|
from GramAddict.core.goap import GoalExecutor
|
|
from GramAddict.core.situational_awareness import SituationalAwarenessEngine
|
|
|
|
TelepathicEngine.reset()
|
|
GoalExecutor.reset()
|
|
SituationalAwarenessEngine.reset()
|
|
|
|
# Aggressively wipe on-disk session files to prevent state leakage in tests
|
|
for f in ["telepathic_memory.json", "telepathic_blacklist.json", "growth_brain_memory.json", "gramaddict_nav_map.json", "l2_channels_cache.json"]:
|
|
if os.path.exists(f):
|
|
try:
|
|
os.remove(f)
|
|
except Exception:
|
|
pass
|
|
yield
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def telepathic_mock(monkeypatch):
|
|
import GramAddict.core.telepathic_engine
|
|
engine = create_mock_telepathic_engine()
|
|
monkeypatch.setattr(GramAddict.core.telepathic_engine.TelepathicEngine, "get_instance", lambda: engine)
|
|
return engine
|
|
|
|
@pytest.fixture
|
|
def mock_cognitive_stack():
|
|
stack = {
|
|
"dopamine": MagicMock(),
|
|
"darwin": MagicMock(),
|
|
"resonance": MagicMock(),
|
|
"active_inference": MagicMock(),
|
|
"growth_brain": MagicMock(),
|
|
"swarm": MagicMock(),
|
|
"radome": MagicMock(),
|
|
"nav_graph": MagicMock(),
|
|
"zero_engine": MagicMock(),
|
|
"crm": MagicMock(),
|
|
"telepathic": create_mock_telepathic_engine()
|
|
}
|
|
stack["radome"].sanitize_xml.side_effect = lambda x: x
|
|
return stack
|