ruff formatting and fixes
This commit is contained in:
@@ -36,6 +36,7 @@ def mock_rns():
|
||||
|
||||
# Mock at the module level for all imports
|
||||
import sys
|
||||
|
||||
sys.modules["RNS"] = mock_rns
|
||||
|
||||
yield mock_rns
|
||||
@@ -51,7 +52,7 @@ def sample_announce_data():
|
||||
return {
|
||||
"destination_hash": "1234567890abcdef",
|
||||
"display_name": "Test Node",
|
||||
"timestamp": 1234567890
|
||||
"timestamp": 1234567890,
|
||||
}
|
||||
|
||||
|
||||
@@ -59,10 +60,9 @@ def sample_announce_data():
|
||||
def sample_page_request():
|
||||
"""Sample page request for testing."""
|
||||
from ren_browser.pages.page_request import PageRequest
|
||||
|
||||
return PageRequest(
|
||||
destination_hash="1234567890abcdef",
|
||||
page_path="/page/index.mu",
|
||||
field_data=None
|
||||
destination_hash="1234567890abcdef", page_path="/page/index.mu", field_data=None
|
||||
)
|
||||
|
||||
|
||||
@@ -75,11 +75,11 @@ def mock_storage_manager():
|
||||
mock_storage.get_config_path.return_value = Mock()
|
||||
mock_storage.get_reticulum_config_path.return_value = Mock()
|
||||
mock_storage.get_storage_info.return_value = {
|
||||
'storage_dir': '/mock/storage',
|
||||
'config_path': '/mock/storage/config.txt',
|
||||
'reticulum_config_path': '/mock/storage/reticulum',
|
||||
'storage_dir_exists': True,
|
||||
'storage_dir_writable': True,
|
||||
'has_client_storage': True,
|
||||
"storage_dir": "/mock/storage",
|
||||
"config_path": "/mock/storage/config.txt",
|
||||
"reticulum_config_path": "/mock/storage/reticulum",
|
||||
"storage_dir_exists": True,
|
||||
"storage_dir_writable": True,
|
||||
"has_client_storage": True,
|
||||
}
|
||||
return mock_storage
|
||||
|
||||
@@ -28,8 +28,14 @@ class TestAppIntegration:
|
||||
def test_entry_points_exist(self):
|
||||
"""Test that all expected entry points exist and are callable."""
|
||||
entry_points = [
|
||||
"run", "web", "android", "ios",
|
||||
"run_dev", "web_dev", "android_dev", "ios_dev"
|
||||
"run",
|
||||
"web",
|
||||
"android",
|
||||
"ios",
|
||||
"run_dev",
|
||||
"web_dev",
|
||||
"android_dev",
|
||||
"ios_dev",
|
||||
]
|
||||
|
||||
for entry_point in entry_points:
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
from ren_browser.announces.announces import Announce
|
||||
|
||||
|
||||
@@ -10,7 +9,7 @@ class TestAnnounce:
|
||||
announce = Announce(
|
||||
destination_hash="1234567890abcdef",
|
||||
display_name="Test Node",
|
||||
timestamp=1234567890
|
||||
timestamp=1234567890,
|
||||
)
|
||||
|
||||
assert announce.destination_hash == "1234567890abcdef"
|
||||
@@ -20,18 +19,17 @@ class TestAnnounce:
|
||||
def test_announce_with_none_display_name(self):
|
||||
"""Test Announce creation with None display name."""
|
||||
announce = Announce(
|
||||
destination_hash="1234567890abcdef",
|
||||
display_name=None,
|
||||
timestamp=1234567890
|
||||
destination_hash="1234567890abcdef", display_name=None, timestamp=1234567890
|
||||
)
|
||||
|
||||
assert announce.destination_hash == "1234567890abcdef"
|
||||
assert announce.display_name is None
|
||||
assert announce.timestamp == 1234567890
|
||||
|
||||
|
||||
class TestAnnounceService:
|
||||
"""Test cases for the AnnounceService class.
|
||||
|
||||
|
||||
Note: These tests are simplified due to complex RNS integration.
|
||||
Full integration tests will be added in the future.
|
||||
"""
|
||||
|
||||
@@ -35,9 +35,7 @@ class TestApp:
|
||||
|
||||
def test_run_with_default_args(self, mock_rns):
|
||||
"""Test run function with default arguments."""
|
||||
with patch("sys.argv", ["ren-browser"]), \
|
||||
patch("flet.app") as mock_ft_app:
|
||||
|
||||
with patch("sys.argv", ["ren-browser"]), patch("flet.app") as mock_ft_app:
|
||||
app.run()
|
||||
|
||||
mock_ft_app.assert_called_once()
|
||||
@@ -46,9 +44,10 @@ class TestApp:
|
||||
|
||||
def test_run_with_web_flag(self, mock_rns):
|
||||
"""Test run function with web flag."""
|
||||
with patch("sys.argv", ["ren-browser", "--web"]), \
|
||||
patch("flet.app") as mock_ft_app:
|
||||
|
||||
with (
|
||||
patch("sys.argv", ["ren-browser", "--web"]),
|
||||
patch("flet.app") as mock_ft_app,
|
||||
):
|
||||
app.run()
|
||||
|
||||
mock_ft_app.assert_called_once()
|
||||
@@ -58,9 +57,10 @@ class TestApp:
|
||||
|
||||
def test_run_with_web_and_port(self, mock_rns):
|
||||
"""Test run function with web flag and custom port."""
|
||||
with patch("sys.argv", ["ren-browser", "--web", "--port", "8080"]), \
|
||||
patch("flet.app") as mock_ft_app:
|
||||
|
||||
with (
|
||||
patch("sys.argv", ["ren-browser", "--web", "--port", "8080"]),
|
||||
patch("flet.app") as mock_ft_app,
|
||||
):
|
||||
app.run()
|
||||
|
||||
mock_ft_app.assert_called_once()
|
||||
@@ -71,9 +71,10 @@ class TestApp:
|
||||
|
||||
def test_run_with_renderer_flag(self, mock_rns):
|
||||
"""Test run function with renderer selection."""
|
||||
with patch("sys.argv", ["ren-browser", "--renderer", "micron"]), \
|
||||
patch("flet.app"):
|
||||
|
||||
with (
|
||||
patch("sys.argv", ["ren-browser", "--renderer", "micron"]),
|
||||
patch("flet.app"),
|
||||
):
|
||||
app.run()
|
||||
|
||||
assert app.RENDERER == "micron"
|
||||
@@ -131,8 +132,10 @@ class TestApp:
|
||||
"""Test that RENDERER global is properly updated."""
|
||||
original_renderer = app.RENDERER
|
||||
|
||||
with patch("sys.argv", ["ren-browser", "--renderer", "micron"]), \
|
||||
patch("flet.app"):
|
||||
with (
|
||||
patch("sys.argv", ["ren-browser", "--renderer", "micron"]),
|
||||
patch("flet.app"),
|
||||
):
|
||||
app.run()
|
||||
assert app.RENDERER == "micron"
|
||||
|
||||
|
||||
@@ -58,7 +58,9 @@ class TestLogsModule:
|
||||
|
||||
assert len(logs.RET_LOGS) == 1
|
||||
assert logs.RET_LOGS[0] == "[2023-01-01T12:00:00] Test RNS message"
|
||||
logs._original_rns_log.assert_called_once_with("Test RNS message", "arg1", kwarg1="value1")
|
||||
logs._original_rns_log.assert_called_once_with(
|
||||
"Test RNS message", "arg1", kwarg1="value1"
|
||||
)
|
||||
assert result == "original_result"
|
||||
|
||||
def test_multiple_log_calls(self):
|
||||
|
||||
@@ -7,8 +7,7 @@ class TestPageRequest:
|
||||
def test_page_request_creation(self):
|
||||
"""Test basic PageRequest creation."""
|
||||
request = PageRequest(
|
||||
destination_hash="1234567890abcdef",
|
||||
page_path="/page/index.mu"
|
||||
destination_hash="1234567890abcdef", page_path="/page/index.mu"
|
||||
)
|
||||
|
||||
assert request.destination_hash == "1234567890abcdef"
|
||||
@@ -21,7 +20,7 @@ class TestPageRequest:
|
||||
request = PageRequest(
|
||||
destination_hash="1234567890abcdef",
|
||||
page_path="/page/form.mu",
|
||||
field_data=field_data
|
||||
field_data=field_data,
|
||||
)
|
||||
|
||||
assert request.destination_hash == "1234567890abcdef"
|
||||
@@ -48,7 +47,7 @@ class TestPageRequest:
|
||||
# These will be implemented when the networking layer is more stable.
|
||||
class TestPageFetcher:
|
||||
"""Test cases for the PageFetcher class.
|
||||
|
||||
|
||||
Note: These tests are simplified due to complex RNS networking integration.
|
||||
Full integration tests will be added when the networking layer is stable.
|
||||
"""
|
||||
@@ -59,7 +58,7 @@ class TestPageFetcher:
|
||||
requests = [
|
||||
PageRequest("hash1", "/index.mu"),
|
||||
PageRequest("hash2", "/about.mu", {"form": "data"}),
|
||||
PageRequest("hash3", "/contact.mu")
|
||||
PageRequest("hash3", "/contact.mu"),
|
||||
]
|
||||
|
||||
# Test that requests have the expected structure
|
||||
|
||||
@@ -57,7 +57,7 @@ class TestPlaintextRenderer:
|
||||
|
||||
class TestMicronRenderer:
|
||||
"""Test cases for the micron renderer.
|
||||
|
||||
|
||||
Note: The micron renderer is currently a placeholder implementation
|
||||
that displays raw content without markup processing.
|
||||
"""
|
||||
|
||||
@@ -215,7 +215,7 @@ class TestShortcuts:
|
||||
url_field2 = Mock()
|
||||
mock_tab_manager.manager.tabs = [
|
||||
{"url_field": url_field1},
|
||||
{"url_field": url_field2}
|
||||
{"url_field": url_field2},
|
||||
]
|
||||
mock_tab_manager.manager.index = 1 # Second tab
|
||||
|
||||
|
||||
@@ -5,7 +5,11 @@ from unittest.mock import Mock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from ren_browser.storage.storage import StorageManager, get_storage_manager, initialize_storage
|
||||
from ren_browser.storage.storage import (
|
||||
StorageManager,
|
||||
get_storage_manager,
|
||||
initialize_storage,
|
||||
)
|
||||
|
||||
|
||||
class TestStorageManager:
|
||||
@@ -13,13 +17,15 @@ class TestStorageManager:
|
||||
|
||||
def test_storage_manager_init_without_page(self):
|
||||
"""Test StorageManager initialization without a page."""
|
||||
with patch('ren_browser.storage.storage.StorageManager._get_storage_directory') as mock_get_dir:
|
||||
mock_dir = Path('/mock/storage')
|
||||
with patch(
|
||||
"ren_browser.storage.storage.StorageManager._get_storage_directory"
|
||||
) as mock_get_dir:
|
||||
mock_dir = Path("/mock/storage")
|
||||
mock_get_dir.return_value = mock_dir
|
||||
|
||||
with patch('pathlib.Path.mkdir') as mock_mkdir:
|
||||
|
||||
with patch("pathlib.Path.mkdir") as mock_mkdir:
|
||||
storage = StorageManager()
|
||||
|
||||
|
||||
assert storage.page is None
|
||||
assert storage._storage_dir == mock_dir
|
||||
mock_mkdir.assert_called_once_with(parents=True, exist_ok=True)
|
||||
@@ -27,27 +33,34 @@ class TestStorageManager:
|
||||
def test_storage_manager_init_with_page(self):
|
||||
"""Test StorageManager initialization with a page."""
|
||||
mock_page = Mock()
|
||||
|
||||
with patch('ren_browser.storage.storage.StorageManager._get_storage_directory') as mock_get_dir:
|
||||
mock_dir = Path('/mock/storage')
|
||||
|
||||
with patch(
|
||||
"ren_browser.storage.storage.StorageManager._get_storage_directory"
|
||||
) as mock_get_dir:
|
||||
mock_dir = Path("/mock/storage")
|
||||
mock_get_dir.return_value = mock_dir
|
||||
|
||||
with patch('pathlib.Path.mkdir'):
|
||||
|
||||
with patch("pathlib.Path.mkdir"):
|
||||
storage = StorageManager(mock_page)
|
||||
|
||||
|
||||
assert storage.page == mock_page
|
||||
assert storage._storage_dir == mock_dir
|
||||
|
||||
def test_get_storage_directory_desktop(self):
|
||||
"""Test storage directory detection for desktop platforms."""
|
||||
with patch('os.name', 'posix'), \
|
||||
patch.dict('os.environ', {'XDG_CONFIG_HOME': '/home/user/.config'}, clear=True), \
|
||||
patch('pathlib.Path.mkdir'):
|
||||
|
||||
with patch('ren_browser.storage.storage.StorageManager._ensure_storage_directory'):
|
||||
with (
|
||||
patch("os.name", "posix"),
|
||||
patch.dict(
|
||||
"os.environ", {"XDG_CONFIG_HOME": "/home/user/.config"}, clear=True
|
||||
),
|
||||
patch("pathlib.Path.mkdir"),
|
||||
):
|
||||
with patch(
|
||||
"ren_browser.storage.storage.StorageManager._ensure_storage_directory"
|
||||
):
|
||||
storage = StorageManager()
|
||||
storage._storage_dir = storage._get_storage_directory()
|
||||
expected_dir = Path('/home/user/.config') / 'ren_browser'
|
||||
expected_dir = Path("/home/user/.config") / "ren_browser"
|
||||
assert storage._storage_dir == expected_dir
|
||||
|
||||
def test_get_storage_directory_windows(self):
|
||||
@@ -57,14 +70,17 @@ class TestStorageManager:
|
||||
|
||||
def test_get_storage_directory_android(self):
|
||||
"""Test storage directory detection for Android."""
|
||||
with patch('os.name', 'posix'), \
|
||||
patch.dict('os.environ', {'ANDROID_ROOT': '/system'}, clear=True), \
|
||||
patch('pathlib.Path.mkdir'):
|
||||
|
||||
with patch('ren_browser.storage.storage.StorageManager._ensure_storage_directory'):
|
||||
with (
|
||||
patch("os.name", "posix"),
|
||||
patch.dict("os.environ", {"ANDROID_ROOT": "/system"}, clear=True),
|
||||
patch("pathlib.Path.mkdir"),
|
||||
):
|
||||
with patch(
|
||||
"ren_browser.storage.storage.StorageManager._ensure_storage_directory"
|
||||
):
|
||||
storage = StorageManager()
|
||||
storage._storage_dir = storage._get_storage_directory()
|
||||
expected_dir = Path('/data/data/com.ren_browser/files')
|
||||
expected_dir = Path("/data/data/com.ren_browser/files")
|
||||
assert storage._storage_dir == expected_dir
|
||||
|
||||
def test_get_config_path(self):
|
||||
@@ -72,17 +88,17 @@ class TestStorageManager:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
storage = StorageManager()
|
||||
storage._storage_dir = Path(temp_dir)
|
||||
|
||||
|
||||
config_path = storage.get_config_path()
|
||||
expected_path = Path(temp_dir) / 'config'
|
||||
expected_path = Path(temp_dir) / "config"
|
||||
assert config_path == expected_path
|
||||
|
||||
def test_get_reticulum_config_path(self):
|
||||
"""Test getting Reticulum config directory path."""
|
||||
storage = StorageManager()
|
||||
|
||||
|
||||
config_path = storage.get_reticulum_config_path()
|
||||
expected_path = Path.home() / '.reticulum'
|
||||
expected_path = Path.home() / ".reticulum"
|
||||
assert config_path == expected_path
|
||||
|
||||
def test_save_config_success(self):
|
||||
@@ -90,52 +106,71 @@ class TestStorageManager:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
storage = StorageManager()
|
||||
storage._storage_dir = Path(temp_dir)
|
||||
|
||||
|
||||
# Mock the reticulum config path to use temp dir
|
||||
with patch.object(storage, 'get_reticulum_config_path', return_value=Path(temp_dir) / "reticulum"):
|
||||
with patch.object(
|
||||
storage,
|
||||
"get_reticulum_config_path",
|
||||
return_value=Path(temp_dir) / "reticulum",
|
||||
):
|
||||
config_content = "test config content"
|
||||
result = storage.save_config(config_content)
|
||||
|
||||
|
||||
assert result is True
|
||||
config_path = storage.get_config_path()
|
||||
assert config_path.exists()
|
||||
assert config_path.read_text(encoding='utf-8') == config_content
|
||||
assert config_path.read_text(encoding="utf-8") == config_content
|
||||
|
||||
def test_save_config_with_client_storage(self):
|
||||
"""Test config saving with client storage."""
|
||||
mock_page = Mock()
|
||||
mock_page.client_storage.set = Mock()
|
||||
|
||||
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
storage = StorageManager(mock_page)
|
||||
storage._storage_dir = Path(temp_dir)
|
||||
|
||||
|
||||
# Mock the reticulum config path to use temp dir
|
||||
with patch.object(storage, 'get_reticulum_config_path', return_value=Path(temp_dir) / "reticulum"):
|
||||
with patch.object(
|
||||
storage,
|
||||
"get_reticulum_config_path",
|
||||
return_value=Path(temp_dir) / "reticulum",
|
||||
):
|
||||
config_content = "test config content"
|
||||
result = storage.save_config(config_content)
|
||||
|
||||
|
||||
assert result is True
|
||||
mock_page.client_storage.set.assert_called_with('ren_browser_config', config_content)
|
||||
mock_page.client_storage.set.assert_called_with(
|
||||
"ren_browser_config", config_content
|
||||
)
|
||||
|
||||
def test_save_config_fallback(self):
|
||||
"""Test config saving fallback when file system fails."""
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
mock_page = Mock()
|
||||
mock_page.client_storage.set = Mock()
|
||||
|
||||
|
||||
storage = StorageManager(mock_page)
|
||||
storage._storage_dir = Path(temp_dir)
|
||||
|
||||
|
||||
# Mock the reticulum config path to use temp dir and cause failure
|
||||
with patch.object(storage, 'get_reticulum_config_path', return_value=Path(temp_dir) / "reticulum"):
|
||||
with patch('pathlib.Path.write_text', side_effect=PermissionError("Access denied")):
|
||||
with patch.object(
|
||||
storage,
|
||||
"get_reticulum_config_path",
|
||||
return_value=Path(temp_dir) / "reticulum",
|
||||
):
|
||||
with patch(
|
||||
"pathlib.Path.write_text",
|
||||
side_effect=PermissionError("Access denied"),
|
||||
):
|
||||
config_content = "test config content"
|
||||
result = storage.save_config(config_content)
|
||||
|
||||
|
||||
assert result is True
|
||||
# Check that the config was set to client storage
|
||||
mock_page.client_storage.set.assert_any_call('ren_browser_config', config_content)
|
||||
mock_page.client_storage.set.assert_any_call(
|
||||
"ren_browser_config", config_content
|
||||
)
|
||||
# Verify that client storage was called at least once
|
||||
assert mock_page.client_storage.set.call_count >= 1
|
||||
|
||||
@@ -144,13 +179,17 @@ class TestStorageManager:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
storage = StorageManager()
|
||||
storage._storage_dir = Path(temp_dir)
|
||||
|
||||
|
||||
# Mock the reticulum config path to use temp dir
|
||||
with patch.object(storage, 'get_reticulum_config_path', return_value=Path(temp_dir) / "reticulum"):
|
||||
with patch.object(
|
||||
storage,
|
||||
"get_reticulum_config_path",
|
||||
return_value=Path(temp_dir) / "reticulum",
|
||||
):
|
||||
config_content = "test config content"
|
||||
config_path = storage.get_config_path()
|
||||
config_path.write_text(config_content, encoding='utf-8')
|
||||
|
||||
config_path.write_text(config_content, encoding="utf-8")
|
||||
|
||||
loaded_config = storage.load_config()
|
||||
assert loaded_config == config_content
|
||||
|
||||
@@ -158,25 +197,33 @@ class TestStorageManager:
|
||||
"""Test loading config from client storage when file doesn't exist."""
|
||||
mock_page = Mock()
|
||||
mock_page.client_storage.get = Mock(return_value="client storage config")
|
||||
|
||||
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
storage = StorageManager(mock_page)
|
||||
storage._storage_dir = Path(temp_dir)
|
||||
|
||||
|
||||
# Mock the reticulum config path to also be in temp dir
|
||||
with patch.object(storage, 'get_reticulum_config_path', return_value=Path(temp_dir) / "reticulum"):
|
||||
with patch.object(
|
||||
storage,
|
||||
"get_reticulum_config_path",
|
||||
return_value=Path(temp_dir) / "reticulum",
|
||||
):
|
||||
loaded_config = storage.load_config()
|
||||
assert loaded_config == "client storage config"
|
||||
mock_page.client_storage.get.assert_called_with('ren_browser_config')
|
||||
mock_page.client_storage.get.assert_called_with("ren_browser_config")
|
||||
|
||||
def test_load_config_default(self):
|
||||
"""Test loading default config when no config exists."""
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
storage = StorageManager()
|
||||
storage._storage_dir = Path(temp_dir)
|
||||
|
||||
|
||||
# Mock the reticulum config path to also be in temp dir
|
||||
with patch.object(storage, 'get_reticulum_config_path', return_value=Path(temp_dir) / "reticulum"):
|
||||
with patch.object(
|
||||
storage,
|
||||
"get_reticulum_config_path",
|
||||
return_value=Path(temp_dir) / "reticulum",
|
||||
):
|
||||
loaded_config = storage.load_config()
|
||||
assert loaded_config == ""
|
||||
|
||||
@@ -185,15 +232,15 @@ class TestStorageManager:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
storage = StorageManager()
|
||||
storage._storage_dir = Path(temp_dir)
|
||||
|
||||
|
||||
bookmarks = [{"name": "Test", "url": "test://example"}]
|
||||
result = storage.save_bookmarks(bookmarks)
|
||||
|
||||
|
||||
assert result is True
|
||||
bookmarks_path = storage._storage_dir / 'bookmarks.json'
|
||||
bookmarks_path = storage._storage_dir / "bookmarks.json"
|
||||
assert bookmarks_path.exists()
|
||||
|
||||
with open(bookmarks_path, 'r', encoding='utf-8') as f:
|
||||
|
||||
with open(bookmarks_path, "r", encoding="utf-8") as f:
|
||||
loaded_bookmarks = json.load(f)
|
||||
assert loaded_bookmarks == bookmarks
|
||||
|
||||
@@ -202,13 +249,13 @@ class TestStorageManager:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
storage = StorageManager()
|
||||
storage._storage_dir = Path(temp_dir)
|
||||
|
||||
|
||||
bookmarks = [{"name": "Test", "url": "test://example"}]
|
||||
bookmarks_path = storage._storage_dir / 'bookmarks.json'
|
||||
|
||||
with open(bookmarks_path, 'w', encoding='utf-8') as f:
|
||||
bookmarks_path = storage._storage_dir / "bookmarks.json"
|
||||
|
||||
with open(bookmarks_path, "w", encoding="utf-8") as f:
|
||||
json.dump(bookmarks, f)
|
||||
|
||||
|
||||
loaded_bookmarks = storage.load_bookmarks()
|
||||
assert loaded_bookmarks == bookmarks
|
||||
|
||||
@@ -217,7 +264,7 @@ class TestStorageManager:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
storage = StorageManager()
|
||||
storage._storage_dir = Path(temp_dir)
|
||||
|
||||
|
||||
loaded_bookmarks = storage.load_bookmarks()
|
||||
assert loaded_bookmarks == []
|
||||
|
||||
@@ -226,15 +273,15 @@ class TestStorageManager:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
storage = StorageManager()
|
||||
storage._storage_dir = Path(temp_dir)
|
||||
|
||||
|
||||
history = [{"url": "test://example", "timestamp": 1234567890}]
|
||||
result = storage.save_history(history)
|
||||
|
||||
|
||||
assert result is True
|
||||
history_path = storage._storage_dir / 'history.json'
|
||||
history_path = storage._storage_dir / "history.json"
|
||||
assert history_path.exists()
|
||||
|
||||
with open(history_path, 'r', encoding='utf-8') as f:
|
||||
|
||||
with open(history_path, "r", encoding="utf-8") as f:
|
||||
loaded_history = json.load(f)
|
||||
assert loaded_history == history
|
||||
|
||||
@@ -243,13 +290,13 @@ class TestStorageManager:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
storage = StorageManager()
|
||||
storage._storage_dir = Path(temp_dir)
|
||||
|
||||
|
||||
history = [{"url": "test://example", "timestamp": 1234567890}]
|
||||
history_path = storage._storage_dir / 'history.json'
|
||||
|
||||
with open(history_path, 'w', encoding='utf-8') as f:
|
||||
history_path = storage._storage_dir / "history.json"
|
||||
|
||||
with open(history_path, "w", encoding="utf-8") as f:
|
||||
json.dump(history, f)
|
||||
|
||||
|
||||
loaded_history = storage.load_history()
|
||||
assert loaded_history == history
|
||||
|
||||
@@ -258,33 +305,36 @@ class TestStorageManager:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
mock_page = Mock()
|
||||
mock_page.client_storage = Mock()
|
||||
|
||||
|
||||
storage = StorageManager(mock_page)
|
||||
storage._storage_dir = Path(temp_dir)
|
||||
|
||||
|
||||
info = storage.get_storage_info()
|
||||
|
||||
assert 'storage_dir' in info
|
||||
assert 'config_path' in info
|
||||
assert 'reticulum_config_path' in info
|
||||
assert 'storage_dir_exists' in info
|
||||
assert 'storage_dir_writable' in info
|
||||
assert 'has_client_storage' in info
|
||||
|
||||
assert info['storage_dir'] == str(Path(temp_dir))
|
||||
assert info['storage_dir_exists'] is True
|
||||
assert info['has_client_storage'] is True
|
||||
|
||||
assert "storage_dir" in info
|
||||
assert "config_path" in info
|
||||
assert "reticulum_config_path" in info
|
||||
assert "storage_dir_exists" in info
|
||||
assert "storage_dir_writable" in info
|
||||
assert "has_client_storage" in info
|
||||
|
||||
assert info["storage_dir"] == str(Path(temp_dir))
|
||||
assert info["storage_dir_exists"] is True
|
||||
assert info["has_client_storage"] is True
|
||||
|
||||
def test_storage_directory_fallback(self):
|
||||
"""Test fallback to temp directory when storage creation fails."""
|
||||
with patch.object(StorageManager, '_get_storage_directory') as mock_get_dir:
|
||||
mock_get_dir.return_value = Path('/nonexistent/path')
|
||||
|
||||
with patch('pathlib.Path.mkdir', side_effect=[PermissionError("Access denied"), None]):
|
||||
with patch('tempfile.gettempdir', return_value='/tmp'):
|
||||
with patch.object(StorageManager, "_get_storage_directory") as mock_get_dir:
|
||||
mock_get_dir.return_value = Path("/nonexistent/path")
|
||||
|
||||
with patch(
|
||||
"pathlib.Path.mkdir",
|
||||
side_effect=[PermissionError("Access denied"), None],
|
||||
):
|
||||
with patch("tempfile.gettempdir", return_value="/tmp"):
|
||||
storage = StorageManager()
|
||||
|
||||
expected_fallback = Path('/tmp') / 'ren_browser'
|
||||
|
||||
expected_fallback = Path("/tmp") / "ren_browser"
|
||||
assert storage._storage_dir == expected_fallback
|
||||
|
||||
|
||||
@@ -293,28 +343,28 @@ class TestStorageGlobalFunctions:
|
||||
|
||||
def test_get_storage_manager_singleton(self):
|
||||
"""Test that get_storage_manager returns the same instance."""
|
||||
with patch('ren_browser.storage.storage._storage_manager', None):
|
||||
with patch("ren_browser.storage.storage._storage_manager", None):
|
||||
storage1 = get_storage_manager()
|
||||
storage2 = get_storage_manager()
|
||||
|
||||
|
||||
assert storage1 is storage2
|
||||
|
||||
def test_get_storage_manager_with_page(self):
|
||||
"""Test get_storage_manager with page parameter."""
|
||||
mock_page = Mock()
|
||||
|
||||
with patch('ren_browser.storage.storage._storage_manager', None):
|
||||
|
||||
with patch("ren_browser.storage.storage._storage_manager", None):
|
||||
storage = get_storage_manager(mock_page)
|
||||
|
||||
|
||||
assert storage.page == mock_page
|
||||
|
||||
def test_initialize_storage(self):
|
||||
"""Test initialize_storage function."""
|
||||
mock_page = Mock()
|
||||
|
||||
with patch('ren_browser.storage.storage._storage_manager', None):
|
||||
|
||||
with patch("ren_browser.storage.storage._storage_manager", None):
|
||||
storage = initialize_storage(mock_page)
|
||||
|
||||
|
||||
assert storage.page == mock_page
|
||||
assert get_storage_manager() is storage
|
||||
|
||||
@@ -327,11 +377,18 @@ class TestStorageManagerEdgeCases:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
storage = StorageManager()
|
||||
storage._storage_dir = Path(temp_dir)
|
||||
|
||||
|
||||
# Mock the reticulum config path to use temp dir
|
||||
with patch.object(storage, 'get_reticulum_config_path', return_value=Path(temp_dir) / "reticulum"):
|
||||
with patch.object(
|
||||
storage,
|
||||
"get_reticulum_config_path",
|
||||
return_value=Path(temp_dir) / "reticulum",
|
||||
):
|
||||
# Test with content that might cause encoding issues
|
||||
with patch('pathlib.Path.write_text', side_effect=UnicodeEncodeError('utf-8', '', 0, 1, 'error')):
|
||||
with patch(
|
||||
"pathlib.Path.write_text",
|
||||
side_effect=UnicodeEncodeError("utf-8", "", 0, 1, "error"),
|
||||
):
|
||||
result = storage.save_config("test content")
|
||||
# Should still succeed due to fallback
|
||||
assert result is False
|
||||
@@ -341,13 +398,17 @@ class TestStorageManagerEdgeCases:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
storage = StorageManager()
|
||||
storage._storage_dir = Path(temp_dir)
|
||||
|
||||
|
||||
# Create a config file with invalid encoding
|
||||
config_path = storage.get_config_path()
|
||||
config_path.write_bytes(b'\xff\xfe invalid utf-8')
|
||||
|
||||
config_path.write_bytes(b"\xff\xfe invalid utf-8")
|
||||
|
||||
# Mock the reticulum config path to also be in temp dir
|
||||
with patch.object(storage, 'get_reticulum_config_path', return_value=Path(temp_dir) / "reticulum"):
|
||||
with patch.object(
|
||||
storage,
|
||||
"get_reticulum_config_path",
|
||||
return_value=Path(temp_dir) / "reticulum",
|
||||
):
|
||||
# Should return empty string when encoding fails
|
||||
config = storage.load_config()
|
||||
assert config == ""
|
||||
@@ -355,9 +416,11 @@ class TestStorageManagerEdgeCases:
|
||||
def test_is_writable_permission_denied(self):
|
||||
"""Test _is_writable when permission is denied."""
|
||||
storage = StorageManager()
|
||||
|
||||
with patch('pathlib.Path.write_text', side_effect=PermissionError("Access denied")):
|
||||
test_path = Path('/mock/path')
|
||||
|
||||
with patch(
|
||||
"pathlib.Path.write_text", side_effect=PermissionError("Access denied")
|
||||
):
|
||||
test_path = Path("/mock/path")
|
||||
result = storage._is_writable(test_path)
|
||||
assert result is False
|
||||
|
||||
@@ -366,6 +429,6 @@ class TestStorageManagerEdgeCases:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
storage = StorageManager()
|
||||
test_path = Path(temp_dir)
|
||||
|
||||
|
||||
result = storage._is_writable(test_path)
|
||||
assert result is True
|
||||
|
||||
@@ -13,17 +13,19 @@ class TestTabsManager:
|
||||
@pytest.fixture
|
||||
def tabs_manager(self, mock_page):
|
||||
"""Create a TabsManager instance for testing."""
|
||||
with patch("ren_browser.app.RENDERER", "plaintext"), \
|
||||
patch("ren_browser.renderer.plaintext.render_plaintext") as mock_render:
|
||||
|
||||
with (
|
||||
patch("ren_browser.app.RENDERER", "plaintext"),
|
||||
patch("ren_browser.renderer.plaintext.render_plaintext") as mock_render,
|
||||
):
|
||||
mock_render.return_value = Mock(spec=ft.Text)
|
||||
return TabsManager(mock_page)
|
||||
|
||||
def test_tabs_manager_init(self, mock_page):
|
||||
"""Test TabsManager initialization."""
|
||||
with patch("ren_browser.app.RENDERER", "plaintext"), \
|
||||
patch("ren_browser.renderer.plaintext.render_plaintext") as mock_render:
|
||||
|
||||
with (
|
||||
patch("ren_browser.app.RENDERER", "plaintext"),
|
||||
patch("ren_browser.renderer.plaintext.render_plaintext") as mock_render,
|
||||
):
|
||||
mock_render.return_value = Mock(spec=ft.Text)
|
||||
manager = TabsManager(mock_page)
|
||||
|
||||
@@ -55,9 +57,10 @@ class TestTabsManager:
|
||||
|
||||
def test_on_add_click(self, tabs_manager):
|
||||
"""Test adding a new tab via button click."""
|
||||
with patch("ren_browser.app.RENDERER", "plaintext"), \
|
||||
patch("ren_browser.renderer.plaintext.render_plaintext") as mock_render:
|
||||
|
||||
with (
|
||||
patch("ren_browser.app.RENDERER", "plaintext"),
|
||||
patch("ren_browser.renderer.plaintext.render_plaintext") as mock_render,
|
||||
):
|
||||
mock_render.return_value = Mock(spec=ft.Text)
|
||||
initial_count = len(tabs_manager.manager.tabs)
|
||||
|
||||
@@ -198,7 +201,7 @@ class TestTabsManager:
|
||||
"""Test management of multiple tabs."""
|
||||
# Add several tabs
|
||||
for i in range(3):
|
||||
tabs_manager._add_tab_internal(f"Tab {i+2}", Mock())
|
||||
tabs_manager._add_tab_internal(f"Tab {i + 2}", Mock())
|
||||
|
||||
assert len(tabs_manager.manager.tabs) == 4
|
||||
|
||||
@@ -220,7 +223,13 @@ class TestTabsManager:
|
||||
tabs_manager._add_tab_internal("Tab 3", content2)
|
||||
|
||||
tabs_manager.select_tab(1)
|
||||
assert tabs_manager.content_container.content == tabs_manager.manager.tabs[1]["content"]
|
||||
assert (
|
||||
tabs_manager.content_container.content
|
||||
== tabs_manager.manager.tabs[1]["content"]
|
||||
)
|
||||
|
||||
tabs_manager.select_tab(2)
|
||||
assert tabs_manager.content_container.content == tabs_manager.manager.tabs[2]["content"]
|
||||
assert (
|
||||
tabs_manager.content_container.content
|
||||
== tabs_manager.manager.tabs[2]["content"]
|
||||
)
|
||||
|
||||
@@ -28,7 +28,9 @@ class TestBuildUI:
|
||||
@patch("ren_browser.pages.page_request.PageFetcher")
|
||||
@patch("ren_browser.tabs.tabs.TabsManager")
|
||||
@patch("ren_browser.controls.shortcuts.Shortcuts")
|
||||
def test_build_ui_appbar_setup(self, mock_shortcuts, mock_tabs, mock_fetcher, mock_announce_service, mock_page):
|
||||
def test_build_ui_appbar_setup(
|
||||
self, mock_shortcuts, mock_tabs, mock_fetcher, mock_announce_service, mock_page
|
||||
):
|
||||
"""Test that build_ui sets up the app bar correctly."""
|
||||
mock_tab_manager = Mock()
|
||||
mock_tabs.return_value = mock_tab_manager
|
||||
@@ -48,7 +50,9 @@ class TestBuildUI:
|
||||
@patch("ren_browser.pages.page_request.PageFetcher")
|
||||
@patch("ren_browser.tabs.tabs.TabsManager")
|
||||
@patch("ren_browser.controls.shortcuts.Shortcuts")
|
||||
def test_build_ui_drawer_setup(self, mock_shortcuts, mock_tabs, mock_fetcher, mock_announce_service, mock_page):
|
||||
def test_build_ui_drawer_setup(
|
||||
self, mock_shortcuts, mock_tabs, mock_fetcher, mock_announce_service, mock_page
|
||||
):
|
||||
"""Test that build_ui sets up the drawer correctly."""
|
||||
mock_tab_manager = Mock()
|
||||
mock_tabs.return_value = mock_tab_manager
|
||||
@@ -116,9 +120,10 @@ class TestOpenSettingsTab:
|
||||
mock_tab_manager._add_tab_internal = Mock()
|
||||
mock_tab_manager.select_tab = Mock()
|
||||
|
||||
with patch("pathlib.Path.read_text", return_value="config"), \
|
||||
patch("pathlib.Path.write_text"):
|
||||
|
||||
with (
|
||||
patch("pathlib.Path.read_text", return_value="config"),
|
||||
patch("pathlib.Path.write_text"),
|
||||
):
|
||||
open_settings_tab(mock_page, mock_tab_manager)
|
||||
|
||||
# Get the settings content that was added
|
||||
@@ -129,7 +134,10 @@ class TestOpenSettingsTab:
|
||||
for control in settings_content.controls:
|
||||
if hasattr(control, "controls"):
|
||||
for sub_control in control.controls:
|
||||
if hasattr(sub_control, "text") and sub_control.text == "Save and Restart":
|
||||
if (
|
||||
hasattr(sub_control, "text")
|
||||
and sub_control.text == "Save and Restart"
|
||||
):
|
||||
save_btn = sub_control
|
||||
break
|
||||
|
||||
@@ -142,7 +150,10 @@ class TestOpenSettingsTab:
|
||||
mock_tab_manager._add_tab_internal = Mock()
|
||||
mock_tab_manager.select_tab = Mock()
|
||||
|
||||
with patch('ren_browser.ui.settings.get_storage_manager', return_value=mock_storage_manager):
|
||||
with patch(
|
||||
"ren_browser.ui.settings.get_storage_manager",
|
||||
return_value=mock_storage_manager,
|
||||
):
|
||||
open_settings_tab(mock_page, mock_tab_manager)
|
||||
|
||||
settings_content = mock_tab_manager._add_tab_internal.call_args[0][1]
|
||||
@@ -155,10 +166,14 @@ class TestOpenSettingsTab:
|
||||
mock_tab_manager._add_tab_internal = Mock()
|
||||
mock_tab_manager.select_tab = Mock()
|
||||
|
||||
with patch('ren_browser.ui.settings.get_storage_manager', return_value=mock_storage_manager), \
|
||||
patch("ren_browser.logs.ERROR_LOGS", ["Error 1", "Error 2"]), \
|
||||
patch("ren_browser.logs.RET_LOGS", ["RNS log 1", "RNS log 2"]):
|
||||
|
||||
with (
|
||||
patch(
|
||||
"ren_browser.ui.settings.get_storage_manager",
|
||||
return_value=mock_storage_manager,
|
||||
),
|
||||
patch("ren_browser.logs.ERROR_LOGS", ["Error 1", "Error 2"]),
|
||||
patch("ren_browser.logs.RET_LOGS", ["RNS log 1", "RNS log 2"]),
|
||||
):
|
||||
open_settings_tab(mock_page, mock_tab_manager)
|
||||
|
||||
mock_tab_manager._add_tab_internal.assert_called_once()
|
||||
|
||||
Reference in New Issue
Block a user