use pinakes_core::books::{extract_isbn_from_text, normalize_isbn, parse_author_file_as}; use pinakes_core::enrichment::books::BookEnricher; use pinakes_core::enrichment::googlebooks::GoogleBooksClient; use pinakes_core::enrichment::openlibrary::OpenLibraryClient; use pinakes_core::thumbnail::{extract_epub_cover, generate_book_covers, CoverSize}; #[test] fn test_isbn_normalization() { // Valid ISBN-10 to ISBN-13 conversion (The Hobbit) let result = normalize_isbn("0547928220"); assert!(result.is_ok()); let isbn13 = result.unwrap(); assert_eq!(isbn13.len(), 13); assert!(isbn13.starts_with("978")); // Valid ISBN-13 should return itself let result = normalize_isbn("9780547928227"); assert!(result.is_ok()); assert_eq!(result.unwrap(), "9780547928227"); // ISBN with hyphens should be normalized let result = normalize_isbn("978-0-547-92822-7"); assert!(result.is_ok()); assert_eq!(result.unwrap(), "9780547928227"); // Invalid ISBN let result = normalize_isbn("invalid"); assert!(result.is_err()); } #[test] fn test_isbn_extraction_from_text() { let text = "This book has ISBN-13: 978-0-123-45678-9 in the middle."; let result = extract_isbn_from_text(text); assert!(result.is_some()); let isbn = result.unwrap(); assert!(isbn.contains("978")); let text_isbn10 = "Old format ISBN: 0-123-45678-9"; let result = extract_isbn_from_text(text_isbn10); assert!(result.is_some()); let text_no_isbn = "This text has no ISBN at all."; let result = extract_isbn_from_text(text_no_isbn); assert!(result.is_none()); } #[test] fn test_author_file_as_parsing() { // Standard name: "First Last" -> "Last, First" let result = parse_author_file_as("John Smith"); assert_eq!(result, "Smith, John"); // Single name let result = parse_author_file_as("Shakespeare"); assert_eq!(result, "Shakespeare"); // Multiple middle names let result = parse_author_file_as("John Ronald Reuel Tolkien"); assert_eq!(result, "Tolkien, John Ronald Reuel"); // Already in "Last, First" format let result = parse_author_file_as("Tolkien, J.R.R."); assert_eq!(result, "Tolkien, J.R.R."); } #[test] fn test_book_enricher_creation() { let enricher = BookEnricher::new(None); // Just verify it can be created drop(enricher); let enricher_with_key = BookEnricher::new(Some("test-api-key".to_string())); drop(enricher_with_key); } #[test] fn test_openlibrary_client_creation() { let client = OpenLibraryClient::new(); // Verify client is created successfully drop(client); } #[test] fn test_googlebooks_client_creation() { let client = GoogleBooksClient::new(None); drop(client); let client_with_key = GoogleBooksClient::new(Some("test-key".to_string())); drop(client_with_key); } #[test] fn test_cover_size_dimensions() { assert_eq!(CoverSize::Tiny.dimensions(), Some((64, 64))); assert_eq!(CoverSize::Grid.dimensions(), Some((320, 320))); assert_eq!(CoverSize::Preview.dimensions(), Some((1024, 1024))); assert_eq!(CoverSize::Original.dimensions(), None); } #[test] fn test_cover_size_filenames() { assert_eq!(CoverSize::Tiny.filename(), "tiny.jpg"); assert_eq!(CoverSize::Grid.filename(), "grid.jpg"); assert_eq!(CoverSize::Preview.filename(), "preview.jpg"); assert_eq!(CoverSize::Original.filename(), "original.jpg"); } // Note: The following tests would require actual EPUB files and network access, // so they're marked as ignored by default. Run with --ignored to execute them. #[test] #[ignore] fn test_epub_cover_extraction() { // This test requires a real EPUB file // Create a test EPUB file path let epub_path = std::path::PathBuf::from("test_fixtures/sample.epub"); if !epub_path.exists() { // Skip if test fixture doesn't exist return; } let result = extract_epub_cover(&epub_path); // Should either succeed with Some(data) or None if no cover found assert!(result.is_ok()); } #[test] #[ignore] fn test_book_cover_generation() { // This test requires a sample image use tempfile::tempdir; // Create a minimal 100x100 red PNG in memory let mut img_data = Vec::new(); { use image::{ImageBuffer, Rgb}; let img: ImageBuffer, Vec> = ImageBuffer::from_fn(100, 100, |_, _| Rgb([255u8, 0u8, 0u8])); img.write_to(&mut std::io::Cursor::new(&mut img_data), image::ImageFormat::Png) .unwrap(); } let temp_dir = tempdir().unwrap(); let media_id = pinakes_core::model::MediaId::new(); let result = generate_book_covers(media_id, &img_data, temp_dir.path()); assert!(result.is_ok()); let covers = result.unwrap(); assert_eq!(covers.len(), 4); // tiny, grid, preview, original // Verify all cover files exist for (size, path) in &covers { assert!(path.exists(), "Cover {:?} should exist at {:?}", size, path); } } #[tokio::test] #[ignore] async fn test_openlibrary_isbn_fetch() { // This test requires network access let client = OpenLibraryClient::new(); // Use a known ISBN for "The Hobbit" let result = client.fetch_by_isbn("9780547928227").await; // Should either succeed or fail gracefully // We don't assert success because network might not be available match result { Ok(book) => { assert!(book.title.is_some()); } Err(_) => { // Network error or book not found - acceptable in tests } } } #[tokio::test] #[ignore] async fn test_googlebooks_isbn_fetch() { // This test requires network access let client = GoogleBooksClient::new(None); // Use a known ISBN let result = client.fetch_by_isbn("9780547928227").await; match result { Ok(books) => { if !books.is_empty() { assert!(books[0].volume_info.title.is_some()); } } Err(_) => { // Network error - acceptable in tests } } }