"""
Tests for search page integration
Tests cover:
- Search page rendering
- Search results display
- Search box in navigation
- Empty state handling
- Error state handling
- Pagination controls
"""
import pytest
from pathlib import Path
from starpunk import create_app
from starpunk.notes import create_note
@pytest.fixture
def app(tmp_path):
"""Create test application with FTS5 enabled"""
test_data_dir = tmp_path / "data"
test_data_dir.mkdir(parents=True, exist_ok=True)
test_config = {
"TESTING": True,
"DATABASE_PATH": test_data_dir / "starpunk.db",
"DATA_PATH": test_data_dir,
"NOTES_PATH": test_data_dir / "notes",
"SESSION_SECRET": "test-secret-key",
"ADMIN_ME": "https://test.example.com",
"SITE_URL": "https://example.com",
"SITE_NAME": "Test Blog",
"DEV_MODE": False,
}
app = create_app(config=test_config)
return app
@pytest.fixture
def client(app):
"""Create test client"""
return app.test_client()
@pytest.fixture
def test_notes(app):
"""Create test notes for searching"""
with app.app_context():
notes = []
for i in range(5):
note = create_note(
content=f"# Test Note {i}\n\nThis is test content about topic {i}.",
published=True
)
notes.append(note)
return notes
def test_search_page_renders(client):
"""Test that search page renders without errors"""
response = client.get("/search")
assert response.status_code == 200
assert b"Search Results" in response.data
def test_search_page_shows_empty_state(client):
"""Test that search page shows empty state without query"""
response = client.get("/search")
assert response.status_code == 200
assert b"Enter search terms" in response.data or b"Search" in response.data
def test_search_page_displays_results(client, test_notes):
"""Test that search page displays results"""
response = client.get("/search?q=test")
assert response.status_code == 200
# Should show query and results
assert b"test" in response.data.lower()
assert b"Test Note" in response.data
def test_search_page_displays_result_count(client, test_notes):
"""Test that search page displays result count"""
response = client.get("/search?q=test")
assert response.status_code == 200
# Should show "Found X results"
assert b"Found" in response.data or b"result" in response.data.lower()
def test_search_page_handles_no_results(client, test_notes):
"""Test that search page handles no results gracefully"""
response = client.get("/search?q=nonexistent")
assert response.status_code == 200
# Should show "no results" message
assert b"No results" in response.data or b"didn't match" in response.data
def test_search_page_preserves_query(client, test_notes):
"""Test that search page preserves query in search box"""
response = client.get("/search?q=python")
assert response.status_code == 200
# Search form should have the query pre-filled
assert b'value="python"' in response.data
def test_search_page_shows_pagination(client, test_notes):
"""Test that search page shows pagination controls when appropriate"""
response = client.get("/search?q=test")
assert response.status_code == 200
# May or may not show pagination depending on result count
# Just verify page renders without error
def test_search_page_pagination_links(client, test_notes):
"""Test that pagination links work correctly"""
# Get second page
response = client.get("/search?q=test&offset=20")
assert response.status_code == 200
# Should render without error
assert b"Search Results" in response.data
def test_search_box_in_navigation(client):
"""Test that search box appears in navigation on all pages"""
# Check on homepage
response = client.get("/")
assert response.status_code == 200
assert b'type="search"' in response.data
assert b'name="q"' in response.data
assert b'action="/search"' in response.data
def test_search_box_preserves_query_on_results_page(client, test_notes):
"""Test that search box preserves query on results page"""
response = client.get("/search?q=test")
assert response.status_code == 200
# Navigation search box should also have the query
# (There are two search forms: one in nav, one on the page)
assert response.data.count(b'value="test"') >= 1
def test_search_page_escapes_html_in_query(client):
"""Test that search page escapes HTML in query display"""
response = client.get("/search?q=")
assert response.status_code == 200
# Should not contain unescaped script tag
assert b"" not in response.data
# Should contain escaped version
assert b"<script>" in response.data or b"alert" in response.data
def test_search_page_shows_excerpt_with_highlighting(client, test_notes):
"""Test that search page shows excerpts with highlighting"""
response = client.get("/search?q=test")
assert response.status_code == 200
# Should contain tags for highlighting (from FTS5 snippet)
# or at least show the excerpt
assert b"Test" in response.data
def test_search_page_shows_note_dates(client, test_notes):
"""Test that search page shows note publication dates"""
response = client.get("/search?q=test")
assert response.status_code == 200
# Should contain time element with datetime
assert b"