- Deleted test_auth.py (auth no longer exists) - Rewrote TestOrderDelayRoute -> TestRootRedirectWithOrderDelay using query params - Updated TestHashPageWithRefresh to use ?order=...&delay=... URLs - Added play button query param assertion in TestHashPage - Removed password=None from test_navigation.py seeded_indexers fixture - Formatted with black, all 59 tests passing
125 lines
4.8 KiB
Python
125 lines
4.8 KiB
Python
"""Tests for navigation helper functions."""
|
|
|
|
import argparse
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
import main
|
|
|
|
|
|
@pytest.fixture
|
|
def seeded_indexers(sample_files: dict[str, Path], tmp_path: Path) -> None:
|
|
"""Initialize with a fixed salt so hashes are predictable."""
|
|
args = argparse.Namespace(
|
|
source=str(tmp_path),
|
|
host="127.0.0.1",
|
|
port=0,
|
|
salt="nav-test-salt",
|
|
)
|
|
main.initialize_server(args)
|
|
|
|
|
|
class TestGetNavigationData:
|
|
"""Tests for _get_navigation_data."""
|
|
|
|
def test_returns_all_keys(self, seeded_indexers: None) -> None:
|
|
"""Navigation data contains all required keys."""
|
|
file_hash = list(main.file_mapping.keys())[0]
|
|
data = main._get_navigation_data(file_hash, order=None)
|
|
assert "file_hash" in data
|
|
assert "next_hash" in data
|
|
assert "prev_hash" in data
|
|
assert "filename" in data
|
|
|
|
def test_file_hash_matches_input(self, seeded_indexers: None) -> None:
|
|
"""Returned file_hash matches the input."""
|
|
file_hash = list(main.file_mapping.keys())[0]
|
|
data = main._get_navigation_data(file_hash, order=None)
|
|
assert data["file_hash"] == file_hash
|
|
|
|
def test_sequential_next_and_prev(self, seeded_indexers: None) -> None:
|
|
"""In sequential mode, next and prev are adjacent in the list."""
|
|
keys = list(main.file_mapping.keys())
|
|
if len(keys) < 2:
|
|
pytest.skip("Need at least 2 files for sequential navigation")
|
|
file_hash = keys[0]
|
|
data = main._get_navigation_data(file_hash, order=None)
|
|
assert data["next_hash"] == keys[1]
|
|
# First item's prev wraps to last
|
|
assert data["prev_hash"] == keys[-1]
|
|
|
|
def test_middle_item_navigation(self, seeded_indexers: None) -> None:
|
|
"""Middle item has correct prev and next."""
|
|
keys = list(main.file_mapping.keys())
|
|
if len(keys) < 3:
|
|
pytest.skip("Need at least 3 files for middle-item test")
|
|
mid_idx = len(keys) // 2
|
|
file_hash = keys[mid_idx]
|
|
data = main._get_navigation_data(file_hash, order=None)
|
|
assert data["next_hash"] == keys[mid_idx + 1]
|
|
assert data["prev_hash"] == keys[mid_idx - 1]
|
|
|
|
def test_last_item_wraps_next(self, seeded_indexers: None) -> None:
|
|
"""Last item's next wraps to the first item."""
|
|
keys = list(main.file_mapping.keys())
|
|
if len(keys) < 2:
|
|
pytest.skip("Need at least 2 files for wrap test")
|
|
file_hash = keys[-1]
|
|
data = main._get_navigation_data(file_hash, order=None)
|
|
assert data["next_hash"] == keys[0]
|
|
|
|
def test_random_order_returns_different_hashes(self, seeded_indexers: None) -> None:
|
|
"""Random order returns hashes that may differ from current."""
|
|
keys = list(main.file_mapping.keys())
|
|
if len(keys) < 3:
|
|
pytest.skip("Need at least 3 files for random test")
|
|
file_hash = keys[0]
|
|
data = main._get_navigation_data(file_hash, order="random")
|
|
# next and prev should be random (not necessarily adjacent)
|
|
assert data["next_hash"] in keys
|
|
assert data["prev_hash"] in keys
|
|
|
|
def test_filename_is_returned(self, seeded_indexers: None) -> None:
|
|
"""Filename is populated from the indexer."""
|
|
file_hash = list(main.file_mapping.keys())[0]
|
|
data = main._get_navigation_data(file_hash, order=None)
|
|
assert data["filename"] is not None
|
|
assert isinstance(data["filename"], str)
|
|
|
|
|
|
class TestGetRandomHash:
|
|
"""Tests for _get_random_hash."""
|
|
|
|
def test_returns_valid_hash(self, seeded_indexers: None) -> None:
|
|
"""Returns a hash that exists in the mapping."""
|
|
random_hash = main._get_random_hash()
|
|
assert random_hash in main.file_mapping
|
|
|
|
def test_raises_when_empty(self) -> None:
|
|
"""Raises HTTPException when no files are indexed."""
|
|
main.file_mapping.clear()
|
|
with pytest.raises(main.HTTPException) as exc_info:
|
|
main._get_random_hash()
|
|
assert exc_info.value.status_code == 404
|
|
|
|
|
|
class TestFindIndexerForHash:
|
|
"""Tests for _find_indexer_for_hash."""
|
|
|
|
def test_finds_correct_indexer(self, seeded_indexers: None) -> None:
|
|
"""Returns the indexer containing the given hash."""
|
|
file_hash = list(main.file_mapping.keys())[0]
|
|
indexer = main._find_indexer_for_hash(file_hash)
|
|
assert indexer is not None
|
|
assert file_hash in indexer._file_mapping
|
|
|
|
def test_returns_none_for_unknown_hash(self, seeded_indexers: None) -> None:
|
|
"""Returns None for a hash not in any indexer."""
|
|
assert main._find_indexer_for_hash("nonexistent") is None
|
|
|
|
def test_returns_none_when_no_indexers(self) -> None:
|
|
"""Returns None when no indexers are registered."""
|
|
main.indexers.clear()
|
|
assert main._find_indexer_for_hash("any-hash") is None
|