Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I9e0ff5ea33a5cf697473423e88f167ce6a6a6964
202 lines
5.6 KiB
Rust
202 lines
5.6 KiB
Rust
use pinakes_core::{
|
|
books::{extract_isbn_from_text, normalize_isbn, parse_author_file_as},
|
|
enrichment::{
|
|
books::BookEnricher,
|
|
googlebooks::GoogleBooksClient,
|
|
openlibrary::OpenLibraryClient,
|
|
},
|
|
thumbnail::{CoverSize, extract_epub_cover, generate_book_covers},
|
|
};
|
|
|
|
#[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<Rgb<u8>, Vec<u8>> =
|
|
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 {size:?} should exist at {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
|
|
if let Ok(book) = result {
|
|
assert!(book.title.is_some());
|
|
} else {
|
|
// 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;
|
|
|
|
if let Ok(books) = result {
|
|
if !books.is_empty() {
|
|
assert!(books[0].volume_info.title.is_some());
|
|
}
|
|
} else {
|
|
// Network error - acceptable in tests
|
|
}
|
|
}
|