dreader-application/tests/test_library_interaction.py
Duncan Tourolle 284a6e3393
All checks were successful
Python CI / test (push) Successful in 4m30s
library and toc navigation
2025-11-08 12:20:23 +01:00

168 lines
5.8 KiB
Python

"""
Unit tests for library interaction and tap detection.
These tests demonstrate the issue with interactive images in the library
and verify that tap detection works correctly.
"""
import unittest
from pathlib import Path
from dreader import LibraryManager
class TestLibraryInteraction(unittest.TestCase):
"""Test library browsing and tap interaction"""
def setUp(self):
"""Set up test library"""
self.library_path = Path(__file__).parent / 'data' / 'library-epub'
self.library = LibraryManager(
library_path=str(self.library_path),
page_size=(800, 1200)
)
def tearDown(self):
"""Clean up"""
self.library.cleanup()
def test_library_scan(self):
"""Test that library scanning finds books"""
books = self.library.scan_library()
# Should find at least one book
self.assertGreater(len(books), 0, "Library should contain at least one book")
# Each book should have required fields
for book in books:
self.assertIn('path', book)
self.assertIn('title', book)
self.assertIn('filename', book)
def test_library_table_creation(self):
"""Test that library table can be created"""
books = self.library.scan_library()
table = self.library.create_library_table()
# Table should exist
self.assertIsNotNone(table)
# Table should have body rows matching book count
body_rows = list(table.body_rows())
self.assertEqual(len(body_rows), len(books))
def test_library_rendering(self):
"""Test that library can be rendered to image"""
self.library.scan_library()
self.library.create_library_table()
# Render library
image = self.library.render_library()
# Image should be created with correct size
self.assertIsNotNone(image)
self.assertEqual(image.size, self.library.page_size)
def test_tap_detection_first_book(self):
"""Test that tapping on first book row selects it
The entire row is interactive, so tapping anywhere in the row
(not just on the cover image) will select the book.
"""
books = self.library.scan_library()
self.library.create_library_table()
self.library.render_library()
# Tap anywhere in the first book's row
# Based on layout: padding 30px, caption ~40px, first row starts at ~70px
selected_path = self.library.handle_library_tap(x=100, y=100)
# Should select the first book
self.assertIsNotNone(selected_path, "Tap should select a book")
self.assertEqual(selected_path, books[0]['path'], "Should select first book")
def test_tap_detection_second_book(self):
"""Test that tapping on second book selects it"""
books = self.library.scan_library()
if len(books) < 2:
self.skipTest("Need at least 2 books for this test")
self.library.create_library_table()
self.library.render_library()
# Tap in the region of the second book
# Row height is ~180px, so second book is at ~70 + 180 = 250px
selected_path = self.library.handle_library_tap(x=400, y=250)
# Should select the second book
self.assertIsNotNone(selected_path, "Tap should select a book")
self.assertEqual(selected_path, books[1]['path'], "Should select second book")
def test_tap_outside_table(self):
"""Test that tapping outside table returns None"""
self.library.scan_library()
self.library.create_library_table()
self.library.render_library()
# Tap outside the table area (far right)
selected_path = self.library.handle_library_tap(x=1000, y=100)
# Should not select anything
self.assertIsNone(selected_path, "Tap outside table should not select anything")
def test_tap_above_table(self):
"""Test that tapping in caption area returns None"""
self.library.scan_library()
self.library.create_library_table()
self.library.render_library()
# Tap in caption area (above first row)
selected_path = self.library.handle_library_tap(x=400, y=40)
# Should not select anything
self.assertIsNone(selected_path, "Tap in caption should not select anything")
def test_tap_below_last_book(self):
"""Test that tapping below all books returns None"""
books = self.library.scan_library()
self.library.create_library_table()
self.library.render_library()
# Tap way below the last book
# With 5 books and row height 180px: ~70 + (5 * 180) = 970px
selected_path = self.library.handle_library_tap(x=400, y=1100)
# Should not select anything
self.assertIsNone(selected_path, "Tap below last book should not select anything")
def test_multiple_taps(self):
"""Test that multiple taps work correctly"""
books = self.library.scan_library()
if len(books) < 3:
self.skipTest("Need at least 3 books for this test")
self.library.create_library_table()
self.library.render_library()
# Tap first book (row 0: y=60-180)
path1 = self.library.handle_library_tap(x=100, y=100)
self.assertEqual(path1, books[0]['path'])
# Tap second book (row 1: y=181-301)
path2 = self.library.handle_library_tap(x=400, y=250)
self.assertEqual(path2, books[1]['path'])
# Tap third book (row 2: y=302-422)
path3 = self.library.handle_library_tap(x=400, y=360)
self.assertEqual(path3, books[2]['path'])
# All should be different
self.assertNotEqual(path1, path2)
self.assertNotEqual(path2, path3)
self.assertNotEqual(path1, path3)
if __name__ == '__main__':
unittest.main()