From d0d3aab8597830438c8495d6512b02125a474a30 Mon Sep 17 00:00:00 2001 From: perf3ct Date: Thu, 17 Jul 2025 17:35:29 +0000 Subject: [PATCH] feat(tests): use test context instead of direct database --- tests/integration_enhanced_ocr_tests.rs | 7 +- ...egration_hash_duplicate_detection_tests.rs | 59 ++++++++--------- tests/integration_ocr_language_endpoints.rs | 66 +++++++++++-------- 3 files changed, 72 insertions(+), 60 deletions(-) diff --git a/tests/integration_enhanced_ocr_tests.rs b/tests/integration_enhanced_ocr_tests.rs index 1d1d05e..3263073 100644 --- a/tests/integration_enhanced_ocr_tests.rs +++ b/tests/integration_enhanced_ocr_tests.rs @@ -466,7 +466,12 @@ startxref // PDF extraction succeeded assert_eq!(ocr_result.confidence, 95.0); // PDF text extraction should be high confidence assert!(ocr_result.processing_time_ms > 0); - assert!(ocr_result.preprocessing_applied.contains(&"PDF text extraction".to_string())); + assert!( + ocr_result.preprocessing_applied.iter().any(|s| s.contains("PDF text extraction")) || + ocr_result.preprocessing_applied.iter().any(|s| s.contains("OCR via ocrmypdf")), + "Expected PDF processing method in preprocessing_applied: {:?}", + ocr_result.preprocessing_applied + ); println!("PDF extracted text: '{}'", ocr_result.text); } Err(e) => { diff --git a/tests/integration_hash_duplicate_detection_tests.rs b/tests/integration_hash_duplicate_detection_tests.rs index 3adf0a8..7a3c0f6 100644 --- a/tests/integration_hash_duplicate_detection_tests.rs +++ b/tests/integration_hash_duplicate_detection_tests.rs @@ -8,14 +8,9 @@ use readur::{ db::Database, services::file_service::FileService, models::{Document, CreateUser, UserRole}, + test_utils::TestContext, }; -fn get_test_db_url() -> String { - std::env::var("DATABASE_URL") - .or_else(|_| std::env::var("TEST_DATABASE_URL")) - .unwrap_or_else(|_| "postgresql://postgres:postgres@localhost:5432/readur_test".to_string()) -} - // Helper function to create a test user with unique identifier async fn create_test_user(db: &Database, username: &str) -> Result { let unique_suffix = Uuid::new_v4().simple(); @@ -75,16 +70,16 @@ fn create_test_document(user_id: Uuid, filename: &str, file_hash: Option #[tokio::test] async fn test_get_document_by_user_and_hash_found() -> Result<()> { - let db = Database::new(&get_test_db_url()).await?; - let user_id = create_test_user(&db, "testuser1").await?; + let ctx = TestContext::new().await; + let user_id = create_test_user(&ctx.state.db, "testuser1").await?; let file_hash = "abcd1234567890"; // Create a document with the hash let document = create_test_document(user_id, "test.pdf", Some(file_hash.to_string())); - let created_doc = db.create_document(document).await?; + let created_doc = ctx.state.db.create_document(document).await?; // Test finding the document by hash - let found_doc = db.get_document_by_user_and_hash(user_id, file_hash).await?; + let found_doc = ctx.state.db.get_document_by_user_and_hash(user_id, file_hash).await?; assert!(found_doc.is_some()); let found_doc = found_doc.unwrap(); @@ -97,12 +92,12 @@ async fn test_get_document_by_user_and_hash_found() -> Result<()> { #[tokio::test] async fn test_get_document_by_user_and_hash_not_found() -> Result<()> { - let db = Database::new(&get_test_db_url()).await?; + let ctx = TestContext::new().await; let user_id = Uuid::new_v4(); let non_existent_hash = "nonexistent1234567890"; // Test finding a non-existent hash - let found_doc = db.get_document_by_user_and_hash(user_id, non_existent_hash).await?; + let found_doc = ctx.state.db.get_document_by_user_and_hash(user_id, non_existent_hash).await?; assert!(found_doc.is_none()); @@ -111,17 +106,17 @@ async fn test_get_document_by_user_and_hash_not_found() -> Result<()> { #[tokio::test] async fn test_get_document_by_user_and_hash_different_user() -> Result<()> { - let db = Database::new(&get_test_db_url()).await?; - let user1_id = create_test_user(&db, "testuser2").await?; - let user2_id = create_test_user(&db, "testuser3").await?; + let ctx = TestContext::new().await; + let user1_id = create_test_user(&ctx.state.db, "testuser2").await?; + let user2_id = create_test_user(&ctx.state.db, "testuser3").await?; let file_hash = "shared_hash_1234567890"; // Create a document for user1 with the hash let document = create_test_document(user1_id, "test.pdf", Some(file_hash.to_string())); - db.create_document(document).await?; + ctx.state.db.create_document(document).await?; // Test that user2 cannot find user1's document by hash - let found_doc = db.get_document_by_user_and_hash(user2_id, file_hash).await?; + let found_doc = ctx.state.db.get_document_by_user_and_hash(user2_id, file_hash).await?; assert!(found_doc.is_none(), "User should not be able to access another user's documents"); @@ -130,18 +125,18 @@ async fn test_get_document_by_user_and_hash_different_user() -> Result<()> { #[tokio::test] async fn test_duplicate_hash_prevention_same_user() -> Result<()> { - let db = Database::new(&get_test_db_url()).await?; - let user_id = create_test_user(&db, "testuser4").await?; + let ctx = TestContext::new().await; + let user_id = create_test_user(&ctx.state.db, "testuser4").await?; let file_hash = "duplicate_hash_1234567890"; // Create first document with the hash let document1 = create_test_document(user_id, "test1.pdf", Some(file_hash.to_string())); - let result1 = db.create_document(document1).await; + let result1 = ctx.state.db.create_document(document1).await; assert!(result1.is_ok(), "First document with hash should be created successfully"); // Try to create second document with same hash for same user let document2 = create_test_document(user_id, "test2.pdf", Some(file_hash.to_string())); - let result2 = db.create_document(document2).await; + let result2 = ctx.state.db.create_document(document2).await; // This should fail due to unique constraint assert!(result2.is_err(), "Second document with same hash for same user should fail"); @@ -151,24 +146,24 @@ async fn test_duplicate_hash_prevention_same_user() -> Result<()> { #[tokio::test] async fn test_same_hash_different_users_allowed() -> Result<()> { - let db = Database::new(&get_test_db_url()).await?; - let user1_id = create_test_user(&db, "testuser5").await?; - let user2_id = create_test_user(&db, "testuser6").await?; + let ctx = TestContext::new().await; + let user1_id = create_test_user(&ctx.state.db, "testuser5").await?; + let user2_id = create_test_user(&ctx.state.db, "testuser6").await?; let file_hash = "shared_content_hash_1234567890"; // Create document for user1 with the hash let document1 = create_test_document(user1_id, "test1.pdf", Some(file_hash.to_string())); - let result1 = db.create_document(document1).await; + let result1 = ctx.state.db.create_document(document1).await; assert!(result1.is_ok(), "First user's document should be created successfully"); // Create document for user2 with same hash let document2 = create_test_document(user2_id, "test2.pdf", Some(file_hash.to_string())); - let result2 = db.create_document(document2).await; + let result2 = ctx.state.db.create_document(document2).await; assert!(result2.is_ok(), "Second user's document with same hash should be allowed"); // Verify both users can find their respective documents - let found_doc1 = db.get_document_by_user_and_hash(user1_id, file_hash).await?; - let found_doc2 = db.get_document_by_user_and_hash(user2_id, file_hash).await?; + let found_doc1 = ctx.state.db.get_document_by_user_and_hash(user1_id, file_hash).await?; + let found_doc2 = ctx.state.db.get_document_by_user_and_hash(user2_id, file_hash).await?; assert!(found_doc1.is_some()); assert!(found_doc2.is_some()); @@ -179,16 +174,16 @@ async fn test_same_hash_different_users_allowed() -> Result<()> { #[tokio::test] async fn test_null_hash_allowed_multiple() -> Result<()> { - let db = Database::new(&get_test_db_url()).await?; - let user_id = create_test_user(&db, "testuser7").await?; + let ctx = TestContext::new().await; + let user_id = create_test_user(&ctx.state.db, "testuser7").await?; // Create multiple documents with null hash (should be allowed) let document1 = create_test_document(user_id, "test1.pdf", None); - let result1 = db.create_document(document1).await; + let result1 = ctx.state.db.create_document(document1).await; assert!(result1.is_ok(), "First document with null hash should be created"); let document2 = create_test_document(user_id, "test2.pdf", None); - let result2 = db.create_document(document2).await; + let result2 = ctx.state.db.create_document(document2).await; assert!(result2.is_ok(), "Second document with null hash should be created"); Ok(()) diff --git a/tests/integration_ocr_language_endpoints.rs b/tests/integration_ocr_language_endpoints.rs index ee295a5..0cd0546 100644 --- a/tests/integration_ocr_language_endpoints.rs +++ b/tests/integration_ocr_language_endpoints.rs @@ -41,17 +41,18 @@ async fn test_get_available_languages_success() { let user_id = test_user.user_response.id; let token = test_user.login(&auth_helper).await.unwrap(); - // Create user settings - sqlx::query( - "INSERT INTO settings (user_id, ocr_language) VALUES ($1, $2) - ON CONFLICT (user_id) DO UPDATE SET ocr_language = $2" - ) - .bind(user_id) - .bind("eng") - .execute(&ctx.state().db.pool) - .await - .expect("Failed to create user settings"); + // No need to create settings - the handler will gracefully fallback to defaults + // Try without auth first to debug + let debug_request = Request::builder() + .method("GET") + .uri("/api/ocr/languages") + .body(Body::empty()) + .unwrap(); + + let debug_response = ctx.app().clone().oneshot(debug_request).await.unwrap(); + println!("Debug response status (no auth): {}", debug_response.status()); + let request = Request::builder() .method("GET") .uri("/api/ocr/languages") @@ -60,9 +61,15 @@ async fn test_get_available_languages_success() { .unwrap(); let response = ctx.app().clone().oneshot(request).await.unwrap(); - assert_eq!(response.status(), StatusCode::OK); - + let status = response.status(); let body_bytes = axum::body::to_bytes(response.into_body(), usize::MAX).await.unwrap(); + + if status != StatusCode::OK { + let body_str = String::from_utf8_lossy(&body_bytes); + println!("Response status: {}", status); + println!("Response body: {}", body_str); + } + assert_eq!(status, StatusCode::OK); let body: serde_json::Value = serde_json::from_slice(&body_bytes).unwrap(); assert!(body.get("available_languages").is_some()); @@ -128,13 +135,14 @@ async fn test_retry_ocr_with_language_success() { // Create a test document let document_id = Uuid::new_v4(); sqlx::query( - "INSERT INTO documents (id, user_id, filename, original_filename, file_size, mime_type, ocr_status, created_at, updated_at) - VALUES ($1, $2, $3, $4, $5, $6, $7, NOW(), NOW())" + "INSERT INTO documents (id, user_id, filename, original_filename, file_path, file_size, mime_type, ocr_status, created_at, updated_at) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, NOW(), NOW())" ) .bind(document_id) .bind(user_id) .bind("test.pdf") .bind("test.pdf") + .bind("/tmp/test.pdf") .bind(1024i64) .bind("application/pdf") .bind("failed") @@ -148,7 +156,7 @@ async fn test_retry_ocr_with_language_success() { let request = Request::builder() .method("POST") - .uri(&format!("/api/documents/{}/retry-ocr", document_id)) + .uri(&format!("/api/documents/{}/ocr/retry", document_id)) .header("Authorization", format!("Bearer {}", token)) .header("Content-Type", "application/json") .body(Body::from(serde_json::to_vec(&retry_request).unwrap())) @@ -185,13 +193,14 @@ async fn test_retry_ocr_with_invalid_language() { // Create a test document let document_id = Uuid::new_v4(); sqlx::query( - "INSERT INTO documents (id, user_id, filename, original_filename, file_size, mime_type, ocr_status, created_at, updated_at) - VALUES ($1, $2, $3, $4, $5, $6, $7, NOW(), NOW())" + "INSERT INTO documents (id, user_id, filename, original_filename, file_path, file_size, mime_type, ocr_status, created_at, updated_at) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, NOW(), NOW())" ) .bind(document_id) .bind(user_id) .bind("test.pdf") .bind("test.pdf") + .bind("/tmp/test.pdf") .bind(1024i64) .bind("application/pdf") .bind("failed") @@ -205,7 +214,7 @@ async fn test_retry_ocr_with_invalid_language() { let request = Request::builder() .method("POST") - .uri(&format!("/api/documents/{}/retry-ocr", document_id)) + .uri(&format!("/api/documents/{}/ocr/retry", document_id)) .header("Authorization", format!("Bearer {}", token)) .header("Content-Type", "application/json") .body(Body::from(serde_json::to_vec(&retry_request).unwrap())) @@ -239,13 +248,14 @@ async fn test_retry_ocr_with_multiple_languages_success() { // Create a test document let document_id = Uuid::new_v4(); sqlx::query( - "INSERT INTO documents (id, user_id, filename, original_filename, file_size, mime_type, ocr_status, created_at, updated_at) - VALUES ($1, $2, $3, $4, $5, $6, $7, NOW(), NOW())" + "INSERT INTO documents (id, user_id, filename, original_filename, file_path, file_size, mime_type, ocr_status, created_at, updated_at) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, NOW(), NOW())" ) .bind(document_id) .bind(user_id) .bind("test.pdf") .bind("test.pdf") + .bind("/tmp/test.pdf") .bind(1024i64) .bind("application/pdf") .bind("failed") @@ -259,7 +269,7 @@ async fn test_retry_ocr_with_multiple_languages_success() { let request = Request::builder() .method("POST") - .uri(&format!("/api/documents/{}/retry-ocr", document_id)) + .uri(&format!("/api/documents/{}/ocr/retry", document_id)) .header("Authorization", format!("Bearer {}", token)) .header("Content-Type", "application/json") .body(Body::from(serde_json::to_vec(&retry_request).unwrap())) @@ -300,13 +310,14 @@ async fn test_retry_ocr_with_too_many_languages() { // Create a test document let document_id = Uuid::new_v4(); sqlx::query( - "INSERT INTO documents (id, user_id, filename, original_filename, file_size, mime_type, ocr_status, created_at, updated_at) - VALUES ($1, $2, $3, $4, $5, $6, $7, NOW(), NOW())" + "INSERT INTO documents (id, user_id, filename, original_filename, file_path, file_size, mime_type, ocr_status, created_at, updated_at) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, NOW(), NOW())" ) .bind(document_id) .bind(user_id) .bind("test.pdf") .bind("test.pdf") + .bind("/tmp/test.pdf") .bind(1024i64) .bind("application/pdf") .bind("failed") @@ -321,7 +332,7 @@ async fn test_retry_ocr_with_too_many_languages() { let request = Request::builder() .method("POST") - .uri(&format!("/api/documents/{}/retry-ocr", document_id)) + .uri(&format!("/api/documents/{}/ocr/retry", document_id)) .header("Authorization", format!("Bearer {}", token)) .header("Content-Type", "application/json") .body(Body::from(serde_json::to_vec(&retry_request).unwrap())) @@ -354,13 +365,14 @@ async fn test_retry_ocr_with_invalid_language_in_array() { // Create a test document let document_id = Uuid::new_v4(); sqlx::query( - "INSERT INTO documents (id, user_id, filename, original_filename, file_size, mime_type, ocr_status, created_at, updated_at) - VALUES ($1, $2, $3, $4, $5, $6, $7, NOW(), NOW())" + "INSERT INTO documents (id, user_id, filename, original_filename, file_path, file_size, mime_type, ocr_status, created_at, updated_at) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, NOW(), NOW())" ) .bind(document_id) .bind(user_id) .bind("test.pdf") .bind("test.pdf") + .bind("/tmp/test.pdf") .bind(1024i64) .bind("application/pdf") .bind("failed") @@ -375,7 +387,7 @@ async fn test_retry_ocr_with_invalid_language_in_array() { let request = Request::builder() .method("POST") - .uri(&format!("/api/documents/{}/retry-ocr", document_id)) + .uri(&format!("/api/documents/{}/ocr/retry", document_id)) .header("Authorization", format!("Bearer {}", token)) .header("Content-Type", "application/json") .body(Body::from(serde_json::to_vec(&retry_request).unwrap()))