feat(tests): use test context instead of direct database

This commit is contained in:
perf3ct 2025-07-17 17:35:29 +00:00
parent 4baef92bc4
commit 8ae3a9cb49
No known key found for this signature in database
GPG Key ID: 569C4EEC436F5232
3 changed files with 72 additions and 60 deletions

View File

@ -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) => {

View File

@ -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<Uuid> {
let unique_suffix = Uuid::new_v4().simple();
@ -75,16 +70,16 @@ fn create_test_document(user_id: Uuid, filename: &str, file_hash: Option<String>
#[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(())

View File

@ -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()))