fix(tests): allow overriding the API_URL for tests

This commit is contained in:
perf3ct 2025-06-19 00:37:29 +00:00
parent 02fbe3847b
commit 0dabf3b96d
No known key found for this signature in database
GPG Key ID: 569C4EEC436F5232
14 changed files with 201 additions and 171 deletions

View File

@ -15,7 +15,9 @@ use uuid::Uuid;
use readur::models::{CreateUser, LoginRequest, LoginResponse, UserRole};
const BASE_URL: &str = "http://localhost:8001";
fn get_base_url() -> String {
std::env::var("API_URL").unwrap_or_else(|_| "http://localhost:8000".to_string())
}
/// Test client with admin capabilities
struct AdminTestClient {
@ -49,7 +51,7 @@ impl AdminTestClient {
};
let login_response = self.client
.post(&format!("{}/api/auth/login", BASE_URL))
.post(&format!("{}/api/auth/login", get_base_url()))
.json(&login_data)
.send()
.await?;
@ -63,7 +65,7 @@ impl AdminTestClient {
// Get admin user info
let me_response = self.client
.get(&format!("{}/api/auth/me", BASE_URL))
.get(&format!("{}/api/auth/me", get_base_url()))
.header("Authorization", format!("Bearer {}", login_result.token))
.send()
.await?;
@ -95,7 +97,7 @@ impl AdminTestClient {
};
let register_response = self.client
.post(&format!("{}/api/auth/register", BASE_URL))
.post(&format!("{}/api/auth/register", get_base_url()))
.json(&user_data)
.send()
.await?;
@ -111,7 +113,7 @@ impl AdminTestClient {
};
let login_response = self.client
.post(&format!("{}/api/auth/login", BASE_URL))
.post(&format!("{}/api/auth/login", get_base_url()))
.json(&login_data)
.send()
.await?;
@ -125,7 +127,7 @@ impl AdminTestClient {
// Get user info
let me_response = self.client
.get(&format!("{}/api/auth/me", BASE_URL))
.get(&format!("{}/api/auth/me", get_base_url()))
.header("Authorization", format!("Bearer {}", login_result.token))
.send()
.await?;
@ -147,7 +149,7 @@ impl AdminTestClient {
};
let response = self.client
.get(&format!("{}/api/users", BASE_URL))
.get(&format!("{}/api/users", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -172,7 +174,7 @@ impl AdminTestClient {
};
let response = self.client
.post(&format!("{}/api/users", BASE_URL))
.post(&format!("{}/api/users", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.json(&user_data)
.send()
@ -199,7 +201,7 @@ impl AdminTestClient {
};
let response = self.client
.get(&format!("{}/api/users/{}", BASE_URL, user_id))
.get(&format!("{}/api/users/{}", get_base_url(), user_id))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -217,7 +219,7 @@ impl AdminTestClient {
let token = self.admin_token.as_ref().ok_or("Admin not logged in")?;
let response = self.client
.put(&format!("{}/api/users/{}", BASE_URL, user_id))
.put(&format!("{}/api/users/{}", get_base_url(), user_id))
.header("Authorization", format!("Bearer {}", token))
.json(&updates)
.send()
@ -236,7 +238,7 @@ impl AdminTestClient {
let token = self.admin_token.as_ref().ok_or("Admin not logged in")?;
let response = self.client
.delete(&format!("{}/api/users/{}", BASE_URL, user_id))
.delete(&format!("{}/api/users/{}", get_base_url(), user_id))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -257,7 +259,7 @@ impl AdminTestClient {
};
let response = self.client
.get(&format!("{}/api/metrics", BASE_URL))
.get(&format!("{}/api/metrics", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -273,7 +275,7 @@ impl AdminTestClient {
/// Get Prometheus metrics (usually public)
async fn get_prometheus_metrics(&self) -> Result<String, Box<dyn std::error::Error>> {
let response = self.client
.get(&format!("{}/metrics", BASE_URL))
.get(&format!("{}/metrics", get_base_url()))
.send()
.await?;
@ -616,7 +618,7 @@ async fn test_admin_error_handling() {
let token = client.admin_token.as_ref().unwrap();
let invalid_create_response = client.client
.post(&format!("{}/api/users", BASE_URL))
.post(&format!("{}/api/users", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.json(&invalid_user_data)
.send()

View File

@ -22,7 +22,9 @@ use uuid::Uuid;
use readur::models::{CreateUser, LoginRequest, LoginResponse, UserRole, SourceType};
const BASE_URL: &str = "http://localhost:8000";
fn get_base_url() -> String {
std::env::var("API_URL").unwrap_or_else(|_| "http://localhost:8000".to_string())
}
const TIMEOUT: Duration = Duration::from_secs(30);
/// Test client for source management operations
@ -60,7 +62,7 @@ impl SourceTestClient {
};
let register_response = self.client
.post(&format!("{}/api/auth/register", BASE_URL))
.post(&format!("{}/api/auth/register", get_base_url()))
.json(&user_data)
.send()
.await?;
@ -76,7 +78,7 @@ impl SourceTestClient {
};
let login_response = self.client
.post(&format!("{}/api/auth/login", BASE_URL))
.post(&format!("{}/api/auth/login", get_base_url()))
.json(&login_data)
.send()
.await?;
@ -90,7 +92,7 @@ impl SourceTestClient {
// Get user info to store user_id
let me_response = self.client
.get(&format!("{}/api/auth/me", BASE_URL))
.get(&format!("{}/api/auth/me", get_base_url()))
.header("Authorization", format!("Bearer {}", login_result.token))
.send()
.await?;
@ -123,7 +125,7 @@ impl SourceTestClient {
});
let response = self.client
.post(&format!("{}/api/sources", BASE_URL))
.post(&format!("{}/api/sources", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.json(&source_data)
.send()
@ -158,7 +160,7 @@ impl SourceTestClient {
});
let response = self.client
.post(&format!("{}/api/sources", BASE_URL))
.post(&format!("{}/api/sources", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.json(&source_data)
.send()
@ -189,7 +191,7 @@ impl SourceTestClient {
});
let response = self.client
.post(&format!("{}/api/sources", BASE_URL))
.post(&format!("{}/api/sources", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.json(&source_data)
.send()
@ -208,7 +210,7 @@ impl SourceTestClient {
let token = self.token.as_ref().ok_or("Not authenticated")?;
let response = self.client
.get(&format!("{}/api/sources", BASE_URL))
.get(&format!("{}/api/sources", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -226,7 +228,7 @@ impl SourceTestClient {
let token = self.token.as_ref().ok_or("Not authenticated")?;
let response = self.client
.get(&format!("{}/api/sources/{}", BASE_URL, source_id))
.get(&format!("{}/api/sources/{}", get_base_url(), source_id))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -244,7 +246,7 @@ impl SourceTestClient {
let token = self.token.as_ref().ok_or("Not authenticated")?;
let response = self.client
.put(&format!("{}/api/sources/{}", BASE_URL, source_id))
.put(&format!("{}/api/sources/{}", get_base_url(), source_id))
.header("Authorization", format!("Bearer {}", token))
.json(&updates)
.send()
@ -263,7 +265,7 @@ impl SourceTestClient {
let token = self.token.as_ref().ok_or("Not authenticated")?;
let response = self.client
.delete(&format!("{}/api/sources/{}", BASE_URL, source_id))
.delete(&format!("{}/api/sources/{}", get_base_url(), source_id))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -280,7 +282,7 @@ impl SourceTestClient {
let token = self.token.as_ref().ok_or("Not authenticated")?;
let response = self.client
.post(&format!("{}/api/sources/{}/test", BASE_URL, source_id))
.post(&format!("{}/api/sources/{}/test", get_base_url(), source_id))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -298,7 +300,7 @@ impl SourceTestClient {
let token = self.token.as_ref().ok_or("Not authenticated")?;
let response = self.client
.post(&format!("{}/api/sources/{}/sync", BASE_URL, source_id))
.post(&format!("{}/api/sources/{}/sync", get_base_url(), source_id))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -316,7 +318,7 @@ impl SourceTestClient {
let token = self.token.as_ref().ok_or("Not authenticated")?;
let response = self.client
.post(&format!("{}/api/sources/{}/sync/stop", BASE_URL, source_id))
.post(&format!("{}/api/sources/{}/sync/stop", get_base_url(), source_id))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -334,7 +336,7 @@ impl SourceTestClient {
let token = self.token.as_ref().ok_or("Not authenticated")?;
let response = self.client
.post(&format!("{}/api/sources/{}/estimate", BASE_URL, source_id))
.post(&format!("{}/api/sources/{}/estimate", get_base_url(), source_id))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -659,7 +661,7 @@ async fn test_source_error_handling() {
let token = client.token.as_ref().unwrap();
let invalid_response = client.client
.post(&format!("{}/api/sources", BASE_URL))
.post(&format!("{}/api/sources", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.json(&invalid_source_data)
.send()
@ -679,7 +681,7 @@ async fn test_source_error_handling() {
// Test operations without authentication
let unauth_client = Client::new();
let unauth_response = unauth_client
.get(&format!("{}/api/sources", BASE_URL))
.get(&format!("{}/api/sources", get_base_url()))
.send()
.await
.expect("Request should complete");

View File

@ -10,7 +10,9 @@ use uuid::Uuid;
use readur::models::{DocumentResponse, CreateUser, LoginRequest, LoginResponse};
const BASE_URL: &str = "http://localhost:8000";
fn get_base_url() -> String {
std::env::var("API_URL").unwrap_or_else(|_| "http://localhost:8000".to_string())
}
const TIMEOUT: Duration = Duration::from_secs(60);
#[tokio::test]
@ -21,7 +23,7 @@ async fn debug_ocr_content() {
// Check server health
let response = client
.get(&format!("{}/api/health", BASE_URL))
.get(&format!("{}/api/health", get_base_url()))
.timeout(Duration::from_secs(5))
.send()
.await
@ -48,7 +50,7 @@ async fn debug_ocr_content() {
};
let register_response = client
.post(&format!("{}/api/auth/register", BASE_URL))
.post(&format!("{}/api/auth/register", get_base_url()))
.json(&user_data)
.send()
.await
@ -65,7 +67,7 @@ async fn debug_ocr_content() {
};
let login_response = client
.post(&format!("{}/api/auth/login", BASE_URL))
.post(&format!("{}/api/auth/login", get_base_url()))
.json(&login_data)
.send()
.await
@ -100,7 +102,7 @@ async fn debug_ocr_content() {
// Upload documents
let doc1_response = client
.post(&format!("{}/api/documents", BASE_URL))
.post(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.multipart(form1)
.send()
@ -108,7 +110,7 @@ async fn debug_ocr_content() {
.expect("Upload should work");
let doc2_response = client
.post(&format!("{}/api/documents", BASE_URL))
.post(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.multipart(form2)
.send()
@ -130,7 +132,7 @@ async fn debug_ocr_content() {
// Check document 1
if !doc1_completed {
let response = client
.get(&format!("{}/api/documents/{}/ocr", BASE_URL, doc1.id))
.get(&format!("{}/api/documents/{}/ocr", get_base_url(), doc1.id))
.header("Authorization", format!("Bearer {}", token))
.send()
.await
@ -148,7 +150,7 @@ async fn debug_ocr_content() {
// Check document 2
if !doc2_completed {
let response = client
.get(&format!("{}/api/documents/{}/ocr", BASE_URL, doc2.id))
.get(&format!("{}/api/documents/{}/ocr", get_base_url(), doc2.id))
.header("Authorization", format!("Bearer {}", token))
.send()
.await
@ -172,14 +174,14 @@ async fn debug_ocr_content() {
// Now get the actual OCR content and analyze it
let doc1_ocr_response = client
.get(&format!("{}/api/documents/{}/ocr", BASE_URL, doc1.id))
.get(&format!("{}/api/documents/{}/ocr", get_base_url(), doc1.id))
.header("Authorization", format!("Bearer {}", token))
.send()
.await
.expect("OCR endpoint should work");
let doc2_ocr_response = client
.get(&format!("{}/api/documents/{}/ocr", BASE_URL, doc2.id))
.get(&format!("{}/api/documents/{}/ocr", get_base_url(), doc2.id))
.header("Authorization", format!("Bearer {}", token))
.send()
.await

View File

@ -11,7 +11,9 @@ use futures;
use readur::models::{DocumentResponse, CreateUser, LoginRequest, LoginResponse};
const BASE_URL: &str = "http://localhost:8000";
fn get_base_url() -> String {
std::env::var("API_URL").unwrap_or_else(|_| "http://localhost:8000".to_string())
}
const TIMEOUT: Duration = Duration::from_secs(120);
struct PipelineDebugger {
@ -25,7 +27,7 @@ impl PipelineDebugger {
// Check server health
let response = client
.get(&format!("{}/api/health", BASE_URL))
.get(&format!("{}/api/health", get_base_url()))
.timeout(Duration::from_secs(5))
.send()
.await
@ -52,7 +54,7 @@ impl PipelineDebugger {
};
let register_response = client
.post(&format!("{}/api/auth/register", BASE_URL))
.post(&format!("{}/api/auth/register", get_base_url()))
.json(&user_data)
.send()
.await
@ -69,7 +71,7 @@ impl PipelineDebugger {
};
let login_response = client
.post(&format!("{}/api/auth/login", BASE_URL))
.post(&format!("{}/api/auth/login", get_base_url()))
.json(&login_data)
.send()
.await
@ -100,7 +102,7 @@ impl PipelineDebugger {
let upload_start = Instant::now();
let response = self.client
.post(&format!("{}/api/documents", BASE_URL))
.post(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", self.token))
.multipart(form)
.send()
@ -137,7 +139,7 @@ impl PipelineDebugger {
poll_count += 1;
let response = self.client
.get(&format!("{}/api/documents/{}/ocr", BASE_URL, document_id))
.get(&format!("{}/api/documents/{}/ocr", get_base_url(), document_id))
.header("Authorization", format!("Bearer {}", self.token))
.send()
.await
@ -229,7 +231,7 @@ impl PipelineDebugger {
async fn get_all_documents(&self) -> Vec<Value> {
let response = self.client
.get(&format!("{}/api/documents", BASE_URL))
.get(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", self.token))
.send()
.await

View File

@ -21,7 +21,9 @@ use uuid::Uuid;
use readur::models::{CreateUser, LoginRequest, LoginResponse, UserRole};
const BASE_URL: &str = "http://localhost:8000";
fn get_base_url() -> String {
std::env::var("API_URL").unwrap_or_else(|_| "http://localhost:8000".to_string())
}
/// Test client for error handling scenarios
struct ErrorHandlingTestClient {
@ -72,7 +74,7 @@ impl ErrorHandlingTestClient {
};
match self.client
.post(&format!("{}/api/auth/register", BASE_URL))
.post(&format!("{}/api/auth/register", get_base_url()))
.json(&user_data)
.send()
.await
@ -107,7 +109,7 @@ impl ErrorHandlingTestClient {
attempts = 0;
while attempts < max_attempts {
match self.client
.post(&format!("{}/api/auth/login", BASE_URL))
.post(&format!("{}/api/auth/login", get_base_url()))
.json(&login_data)
.send()
.await
@ -152,7 +154,7 @@ async fn test_invalid_authentication_scenarios() {
});
let response = client
.post(&format!("{}/api/auth/login", BASE_URL))
.post(&format!("{}/api/auth/login", get_base_url()))
.json(&empty_login)
.send()
.await
@ -168,7 +170,7 @@ async fn test_invalid_authentication_scenarios() {
});
let response = client
.post(&format!("{}/api/auth/login", BASE_URL))
.post(&format!("{}/api/auth/login", get_base_url()))
.json(&invalid_username)
.send()
.await
@ -184,7 +186,7 @@ async fn test_invalid_authentication_scenarios() {
});
let response = client
.post(&format!("{}/api/auth/login", BASE_URL))
.post(&format!("{}/api/auth/login", get_base_url()))
.json(&sql_injection)
.send()
.await
@ -202,7 +204,7 @@ async fn test_invalid_authentication_scenarios() {
});
let response = client
.post(&format!("{}/api/auth/login", BASE_URL))
.post(&format!("{}/api/auth/login", get_base_url()))
.json(&long_creds)
.send()
.await
@ -213,7 +215,7 @@ async fn test_invalid_authentication_scenarios() {
// Test 5: Invalid JWT token format
let invalid_token_response = client
.get(&format!("{}/api/auth/me", BASE_URL))
.get(&format!("{}/api/auth/me", get_base_url()))
.header("Authorization", "Bearer invalid-jwt-token-format")
.send()
.await
@ -224,7 +226,7 @@ async fn test_invalid_authentication_scenarios() {
// Test 6: Malformed Authorization header
let malformed_auth_response = client
.get(&format!("{}/api/auth/me", BASE_URL))
.get(&format!("{}/api/auth/me", get_base_url()))
.header("Authorization", "InvalidFormat token")
.send()
.await
@ -250,7 +252,7 @@ async fn test_malformed_request_handling() {
// Test 1: Invalid JSON in request body
let invalid_json_response = client.client
.post(&format!("{}/api/sources", BASE_URL))
.post(&format!("{}/api/sources", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.header("Content-Type", "application/json")
.body("{invalid json syntax")
@ -268,7 +270,7 @@ async fn test_malformed_request_handling() {
});
let response = client.client
.post(&format!("{}/api/sources", BASE_URL))
.post(&format!("{}/api/sources", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.json(&missing_fields)
.send()
@ -286,7 +288,7 @@ async fn test_malformed_request_handling() {
});
let response = client.client
.post(&format!("{}/api/sources", BASE_URL))
.post(&format!("{}/api/sources", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.json(&invalid_enum)
.send()
@ -309,7 +311,7 @@ async fn test_malformed_request_handling() {
});
let response = client.client
.post(&format!("{}/api/sources", BASE_URL))
.post(&format!("{}/api/sources", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.json(&invalid_nested)
.send()
@ -337,7 +339,7 @@ async fn test_malformed_request_handling() {
});
let response = client.client
.post(&format!("{}/api/sources", BASE_URL))
.post(&format!("{}/api/sources", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.json(&extra_fields)
.send()
@ -370,7 +372,7 @@ async fn test_file_upload_edge_cases() {
.part("file", empty_part);
let response = client.client
.post(&format!("{}/api/documents", BASE_URL))
.post(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.multipart(empty_form)
.send()
@ -390,7 +392,7 @@ async fn test_file_upload_edge_cases() {
.part("file", long_filename_part);
let response = client.client
.post(&format!("{}/api/documents", BASE_URL))
.post(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.multipart(long_filename_form)
.send()
@ -409,7 +411,7 @@ async fn test_file_upload_edge_cases() {
.part("file", special_filename_part);
let response = client.client
.post(&format!("{}/api/documents", BASE_URL))
.post(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.multipart(special_filename_form)
.send()
@ -423,7 +425,7 @@ async fn test_file_upload_edge_cases() {
.text("not_file", "some text");
let response = client.client
.post(&format!("{}/api/documents", BASE_URL))
.post(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.multipart(no_file_form)
.send()
@ -447,7 +449,7 @@ async fn test_file_upload_edge_cases() {
.part("file2", file2);
let response = client.client
.post(&format!("{}/api/documents", BASE_URL))
.post(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.multipart(multi_file_form)
.send()
@ -466,7 +468,7 @@ async fn test_file_upload_edge_cases() {
.part("file", part);
let response = client.client
.post(&format!("{}/api/documents", BASE_URL))
.post(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.multipart(invalid_mime_form)
.send()
@ -520,7 +522,7 @@ async fn test_concurrent_operation_conflicts() {
});
let response = client_clone
.post(&format!("{}/api/sources", BASE_URL))
.post(&format!("{}/api/sources", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.json(&source_data)
.send()
@ -570,7 +572,7 @@ async fn test_concurrent_operation_conflicts() {
.part("file", part);
let response = client_clone
.post(&format!("{}/api/documents", BASE_URL))
.post(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.multipart(form)
.send()
@ -607,7 +609,7 @@ async fn test_network_timeout_scenarios() {
// Test 1: Registration with timeout
let timeout_result = short_timeout_client.client
.post(&format!("{}/api/auth/register", BASE_URL))
.post(&format!("{}/api/auth/register", get_base_url()))
.json(&json!({
"username": "timeout_test",
"email": "timeout@example.com",
@ -645,7 +647,7 @@ async fn test_network_timeout_scenarios() {
// This should complete within normal timeout
let upload_result = normal_client.client
.post(&format!("{}/api/documents", BASE_URL))
.post(&format!("{}/api/documents", get_base_url()))
.multipart(form)
.send()
.await;
@ -691,7 +693,7 @@ async fn test_resource_exhaustion_simulation() {
let handle = tokio::spawn(async move {
let start = Instant::now();
let response = client_clone
.get(&format!("{}/api/documents", BASE_URL))
.get(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token_clone))
.send()
.await;
@ -738,7 +740,7 @@ async fn test_resource_exhaustion_simulation() {
let large_upload_start = Instant::now();
let large_upload_result = client.client
.post(&format!("{}/api/documents", BASE_URL))
.post(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.multipart(large_form)
.send()
@ -777,7 +779,7 @@ async fn test_database_constraint_violations() {
});
let register_response = client.client
.post(&format!("{}/api/auth/register", BASE_URL))
.post(&format!("{}/api/auth/register", get_base_url()))
.json(&original_user)
.send()
.await
@ -794,7 +796,7 @@ async fn test_database_constraint_violations() {
});
let duplicate_response = client.client
.post(&format!("{}/api/auth/register", BASE_URL))
.post(&format!("{}/api/auth/register", get_base_url()))
.json(&duplicate_email_user)
.send()
.await
@ -821,7 +823,7 @@ async fn test_database_constraint_violations() {
});
let long_name_response = client.client
.post(&format!("{}/api/sources", BASE_URL))
.post(&format!("{}/api/sources", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.json(&long_name_source)
.send()
@ -837,7 +839,7 @@ async fn test_database_constraint_violations() {
// that don't exist or belong to other users
let fake_source_id = Uuid::new_v4().to_string();
let fake_source_response = client.client
.get(&format!("{}/api/sources/{}", BASE_URL, fake_source_id))
.get(&format!("{}/api/sources/{}", get_base_url(), fake_source_id))
.header("Authorization", format!("Bearer {}", token))
.send()
.await

View File

@ -21,7 +21,9 @@ use uuid::Uuid;
use readur::models::{CreateUser, LoginRequest, LoginResponse, UserRole, DocumentResponse};
const BASE_URL: &str = "http://localhost:8000";
fn get_base_url() -> String {
std::env::var("API_URL").unwrap_or_else(|_| "http://localhost:8000".to_string())
}
const PROCESSING_TIMEOUT: Duration = Duration::from_secs(120);
/// Test image structure for pipeline tests
@ -74,7 +76,7 @@ impl FileProcessingTestClient {
};
let register_response = self.client
.post(&format!("{}/api/auth/register", BASE_URL))
.post(&format!("{}/api/auth/register", get_base_url()))
.json(&user_data)
.send()
.await?;
@ -90,7 +92,7 @@ impl FileProcessingTestClient {
};
let login_response = self.client
.post(&format!("{}/api/auth/login", BASE_URL))
.post(&format!("{}/api/auth/login", get_base_url()))
.json(&login_data)
.send()
.await?;
@ -104,7 +106,7 @@ impl FileProcessingTestClient {
// Get user info
let me_response = self.client
.get(&format!("{}/api/auth/me", BASE_URL))
.get(&format!("{}/api/auth/me", get_base_url()))
.header("Authorization", format!("Bearer {}", login_result.token))
.send()
.await?;
@ -128,7 +130,7 @@ impl FileProcessingTestClient {
.part("file", part);
let response = self.client
.post(&format!("{}/api/documents", BASE_URL))
.post(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.multipart(form)
.send()
@ -153,7 +155,7 @@ impl FileProcessingTestClient {
.part("file", part);
let response = self.client
.post(&format!("{}/api/documents", BASE_URL))
.post(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.multipart(form)
.send()
@ -174,7 +176,7 @@ impl FileProcessingTestClient {
while start.elapsed() < PROCESSING_TIMEOUT {
let response = self.client
.get(&format!("{}/api/documents", BASE_URL))
.get(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -222,7 +224,7 @@ impl FileProcessingTestClient {
let token = self.token.as_ref().ok_or("Not authenticated")?;
let response = self.client
.get(&format!("{}/api/documents/{}/thumbnail", BASE_URL, document_id))
.get(&format!("{}/api/documents/{}/thumbnail", get_base_url(), document_id))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -238,7 +240,7 @@ impl FileProcessingTestClient {
let token = self.token.as_ref().ok_or("Not authenticated")?;
let response = self.client
.get(&format!("{}/api/documents/{}/processed-image", BASE_URL, document_id))
.get(&format!("{}/api/documents/{}/processed-image", get_base_url(), document_id))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -254,7 +256,7 @@ impl FileProcessingTestClient {
let token = self.token.as_ref().ok_or("Not authenticated")?;
let response = self.client
.get(&format!("{}/api/documents/{}/ocr", BASE_URL, document_id))
.get(&format!("{}/api/documents/{}/ocr", get_base_url(), document_id))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -272,7 +274,7 @@ impl FileProcessingTestClient {
let token = self.token.as_ref().ok_or("Not authenticated")?;
let response = self.client
.get(&format!("{}/api/documents/{}/download", BASE_URL, document_id))
.get(&format!("{}/api/documents/{}/download", get_base_url(), document_id))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -288,7 +290,7 @@ impl FileProcessingTestClient {
let token = self.token.as_ref().ok_or("Not authenticated")?;
let response = self.client
.get(&format!("{}/api/documents/{}/view", BASE_URL, document_id))
.get(&format!("{}/api/documents/{}/view", get_base_url(), document_id))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -628,7 +630,7 @@ async fn test_processing_error_recovery() {
while start.elapsed() < extended_timeout {
let response = client.client
.get(&format!("{}/api/documents", BASE_URL))
.get(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", client.token.as_ref().unwrap()))
.send()
.await;
@ -864,7 +866,7 @@ async fn test_concurrent_file_processing() {
let start = Instant::now();
let response = client_clone
.post(&format!("{}/api/documents", BASE_URL))
.post(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.multipart(form)
.send()
@ -916,7 +918,7 @@ async fn test_concurrent_file_processing() {
// Wait for processing with timeout
while start.elapsed() < PROCESSING_TIMEOUT {
let response = client_clone
.get(&format!("{}/api/documents", BASE_URL))
.get(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.send()
.await

View File

@ -12,7 +12,10 @@ use tokio::time::sleep;
use readur::models::{DocumentResponse, CreateUser, LoginRequest, LoginResponse};
const BASE_URL: &str = "http://localhost:8000";
fn get_base_url() -> String {
std::env::var("API_URL").unwrap_or_else(|_| "http://localhost:8000".to_string())
}
const TIMEOUT: Duration = Duration::from_secs(30);
/// Integration test client that handles authentication and common operations
@ -32,7 +35,7 @@ impl TestClient {
/// Check if server is running and healthy
async fn check_server_health(&self) -> Result<(), Box<dyn std::error::Error>> {
let response = self.client
.get(&format!("{}/api/health", BASE_URL))
.get(&format!("{}/api/health", get_base_url()))
.timeout(Duration::from_secs(5))
.send()
.await?;
@ -60,7 +63,7 @@ impl TestClient {
};
let register_response = self.client
.post(&format!("{}/api/auth/register", BASE_URL))
.post(&format!("{}/api/auth/register", get_base_url()))
.json(&user_data)
.send()
.await?;
@ -76,7 +79,7 @@ impl TestClient {
};
let login_response = self.client
.post(&format!("{}/api/auth/login", BASE_URL))
.post(&format!("{}/api/auth/login", get_base_url()))
.json(&login_data)
.send()
.await?;
@ -102,7 +105,7 @@ impl TestClient {
.part("file", part);
let response = self.client
.post(&format!("{}/api/documents", BASE_URL))
.post(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.multipart(form)
.send()
@ -123,7 +126,7 @@ impl TestClient {
while start.elapsed() < TIMEOUT {
let response = self.client
.get(&format!("{}/api/documents", BASE_URL))
.get(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -160,7 +163,7 @@ impl TestClient {
let token = self.token.as_ref().ok_or("Not authenticated")?;
let response = self.client
.get(&format!("{}/api/documents/{}/ocr", BASE_URL, document_id))
.get(&format!("{}/api/documents/{}/ocr", get_base_url(), document_id))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -180,7 +183,7 @@ async fn test_complete_ocr_workflow() {
// Check server health
if let Err(e) = client.check_server_health().await {
panic!("Server not running at {}: {}", BASE_URL, e);
panic!("Server not running at {}: {}", get_base_url(), e);
}
// Create test user with unique timestamp
@ -266,7 +269,7 @@ async fn test_ocr_error_handling() {
// Test unauthorized access
let response = client.client
.get(&format!("{}/api/documents/test-id/ocr", BASE_URL))
.get(&format!("{}/api/documents/test-id/ocr", get_base_url()))
.send()
.await
.expect("Failed to make request");
@ -285,7 +288,7 @@ async fn test_ocr_error_handling() {
).await.expect("Failed to register and login");
let response = client.client
.get(&format!("{}/api/documents/00000000-0000-0000-0000-000000000000/ocr", BASE_URL))
.get(&format!("{}/api/documents/00000000-0000-0000-0000-000000000000/ocr", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.send()
.await
@ -327,7 +330,7 @@ async fn test_document_list_structure() {
// Get document list
let response = client.client
.get(&format!("{}/api/documents", BASE_URL))
.get(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", client.token.as_ref().unwrap()))
.send()
.await

View File

@ -11,7 +11,9 @@ use futures;
use readur::models::{DocumentResponse, CreateUser, LoginRequest, LoginResponse};
const BASE_URL: &str = "http://localhost:8000";
fn get_base_url() -> String {
std::env::var("API_URL").unwrap_or_else(|_| "http://localhost:8000".to_string())
}
struct Investigator {
client: Client,
@ -37,7 +39,7 @@ impl Investigator {
role: Some(readur::models::UserRole::User),
};
client.post(&format!("{}/api/auth/register", BASE_URL))
client.post(&format!("{}/api/auth/register", get_base_url()))
.json(&user_data)
.send()
.await
@ -49,7 +51,7 @@ impl Investigator {
};
let login_response = client
.post(&format!("{}/api/auth/login", BASE_URL))
.post(&format!("{}/api/auth/login", get_base_url()))
.json(&login_data)
.send()
.await
@ -69,7 +71,7 @@ impl Investigator {
let form = reqwest::multipart::Form::new().part("file", part);
let response = self.client
.post(&format!("{}/api/documents", BASE_URL))
.post(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", self.token))
.multipart(form)
.send()
@ -81,7 +83,7 @@ impl Investigator {
async fn get_document_details(&self, doc_id: &str) -> Value {
let response = self.client
.get(&format!("{}/api/documents/{}/ocr", BASE_URL, doc_id))
.get(&format!("{}/api/documents/{}/ocr", get_base_url(), doc_id))
.header("Authorization", format!("Bearer {}", self.token))
.send()
.await
@ -92,7 +94,7 @@ impl Investigator {
async fn get_queue_stats(&self) -> Value {
let response = self.client
.get(&format!("{}/api/queue/stats", BASE_URL))
.get(&format!("{}/api/queue/stats", get_base_url()))
.header("Authorization", format!("Bearer {}", self.token))
.send()
.await;

View File

@ -13,7 +13,9 @@ use uuid::Uuid;
use readur::models::{DocumentResponse, CreateUser, LoginRequest, LoginResponse};
const BASE_URL: &str = "http://localhost:8000";
fn get_base_url() -> String {
std::env::var("API_URL").unwrap_or_else(|_| "http://localhost:8000".to_string())
}
const TIMEOUT: Duration = Duration::from_secs(60);
/// Test client for OCR corruption scenarios
@ -34,7 +36,7 @@ impl OcrTestClient {
async fn check_server_health(&self) -> Result<(), Box<dyn std::error::Error>> {
let response = self.client
.get(&format!("{}/api/health", BASE_URL))
.get(&format!("{}/api/health", get_base_url()))
.timeout(Duration::from_secs(5))
.send()
.await?;
@ -55,7 +57,7 @@ impl OcrTestClient {
};
let register_response = self.client
.post(&format!("{}/api/auth/register", BASE_URL))
.post(&format!("{}/api/auth/register", get_base_url()))
.json(&user_data)
.send()
.await?;
@ -70,7 +72,7 @@ impl OcrTestClient {
};
let login_response = self.client
.post(&format!("{}/api/auth/login", BASE_URL))
.post(&format!("{}/api/auth/login", get_base_url()))
.json(&login_data)
.send()
.await?;
@ -96,7 +98,7 @@ impl OcrTestClient {
.part("file", part);
let response = self.client
.post(&format!("{}/api/documents", BASE_URL))
.post(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.multipart(form)
.send()
@ -115,7 +117,7 @@ impl OcrTestClient {
let token = self.token.as_ref().ok_or("Not authenticated")?;
let response = self.client
.get(&format!("{}/api/documents/{}/ocr", BASE_URL, doc_id))
.get(&format!("{}/api/documents/{}/ocr", get_base_url(), doc_id))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -214,7 +216,7 @@ async fn test_concurrent_ocr_corruption() {
// Check server health
if let Err(e) = client.check_server_health().await {
panic!("Server not running at {}: {}", BASE_URL, e);
panic!("Server not running at {}: {}", get_base_url(), e);
}
// Create test user
@ -365,7 +367,7 @@ async fn test_high_volume_concurrent_ocr() {
let mut client = OcrTestClient::new();
if let Err(e) = client.check_server_health().await {
panic!("Server not running at {}: {}", BASE_URL, e);
panic!("Server not running at {}: {}", get_base_url(), e);
}
let timestamp = std::time::SystemTime::now()
@ -468,7 +470,7 @@ async fn test_rapid_sequential_uploads() {
let mut client = OcrTestClient::new();
if let Err(e) = client.check_server_health().await {
panic!("Server not running at {}: {}", BASE_URL, e);
panic!("Server not running at {}: {}", get_base_url(), e);
}
let timestamp = std::time::SystemTime::now()

View File

@ -18,7 +18,9 @@ use uuid::Uuid;
use readur::models::{CreateUser, LoginRequest, LoginResponse, UserRole, DocumentResponse};
const BASE_URL: &str = "http://localhost:8000";
fn get_base_url() -> String {
std::env::var("API_URL").unwrap_or_else(|_| "http://localhost:8000".to_string())
}
const TIMEOUT: Duration = Duration::from_secs(60);
/// Test client for OCR queue operations
@ -56,7 +58,7 @@ impl OCRQueueTestClient {
};
let register_response = self.client
.post(&format!("{}/api/auth/register", BASE_URL))
.post(&format!("{}/api/auth/register", get_base_url()))
.json(&user_data)
.send()
.await?;
@ -72,7 +74,7 @@ impl OCRQueueTestClient {
};
let login_response = self.client
.post(&format!("{}/api/auth/login", BASE_URL))
.post(&format!("{}/api/auth/login", get_base_url()))
.json(&login_data)
.send()
.await?;
@ -86,7 +88,7 @@ impl OCRQueueTestClient {
// Get user info
let me_response = self.client
.get(&format!("{}/api/auth/me", BASE_URL))
.get(&format!("{}/api/auth/me", get_base_url()))
.header("Authorization", format!("Bearer {}", login_result.token))
.send()
.await?;
@ -104,7 +106,7 @@ impl OCRQueueTestClient {
let token = self.token.as_ref().ok_or("Not authenticated")?;
let response = self.client
.get(&format!("{}/api/queue/stats", BASE_URL))
.get(&format!("{}/api/queue/stats", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -122,7 +124,7 @@ impl OCRQueueTestClient {
let token = self.token.as_ref().ok_or("Not authenticated")?;
let response = self.client
.post(&format!("{}/api/queue/requeue-failed", BASE_URL))
.post(&format!("{}/api/queue/requeue-failed", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -146,7 +148,7 @@ impl OCRQueueTestClient {
.part("file", part);
let response = self.client
.post(&format!("{}/api/documents", BASE_URL))
.post(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.multipart(form)
.send()
@ -196,7 +198,7 @@ impl OCRQueueTestClient {
let token = self.token.as_ref().ok_or("Not authenticated")?;
let response = self.client
.get(&format!("{}/api/documents", BASE_URL))
.get(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -228,7 +230,7 @@ impl OCRQueueTestClient {
let token = self.token.as_ref().ok_or("Not authenticated")?;
let response = self.client
.get(&format!("{}/api/documents", BASE_URL))
.get(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -536,7 +538,7 @@ async fn test_queue_error_handling() {
// Test unauthorized access to queue stats
let unauth_client = Client::new();
let unauth_response = unauth_client
.get(&format!("{}/api/queue/stats", BASE_URL))
.get(&format!("{}/api/queue/stats", get_base_url()))
.send()
.await
.expect("Request should complete");
@ -546,7 +548,7 @@ async fn test_queue_error_handling() {
// Test unauthorized requeue attempt
let unauth_requeue_response = unauth_client
.post(&format!("{}/api/queue/requeue-failed", BASE_URL))
.post(&format!("{}/api/queue/requeue-failed", get_base_url()))
.send()
.await
.expect("Request should complete");

View File

@ -22,7 +22,10 @@ use uuid::Uuid;
use readur::models::{CreateUser, LoginRequest, LoginResponse, UserRole, DocumentResponse};
const BASE_URL: &str = "http://localhost:8000";
fn get_base_url() -> String {
std::env::var("API_URL").unwrap_or_else(|_| "http://localhost:8000".to_string())
}
const LOAD_TEST_TIMEOUT: Duration = Duration::from_secs(300); // 5 minutes for load tests
/// Performance metrics tracker
@ -144,7 +147,7 @@ impl LoadTestClient {
};
let register_response = self.client
.post(&format!("{}/api/auth/register", BASE_URL))
.post(&format!("{}/api/auth/register", get_base_url()))
.json(&user_data)
.send()
.await?;
@ -160,7 +163,7 @@ impl LoadTestClient {
};
let login_response = self.client
.post(&format!("{}/api/auth/login", BASE_URL))
.post(&format!("{}/api/auth/login", get_base_url()))
.json(&login_data)
.send()
.await?;
@ -174,7 +177,7 @@ impl LoadTestClient {
// Get user info
let me_response = self.client
.get(&format!("{}/api/auth/me", BASE_URL))
.get(&format!("{}/api/auth/me", get_base_url()))
.header("Authorization", format!("Bearer {}", login_result.token))
.send()
.await?;
@ -199,7 +202,7 @@ impl LoadTestClient {
.part("file", part);
let response = self.client
.post(&format!("{}/api/documents", BASE_URL))
.post(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.multipart(form)
.send()
@ -221,7 +224,7 @@ impl LoadTestClient {
let token = self.token.as_ref().ok_or("Not authenticated")?;
let response = self.client
.get(&format!("{}/api/documents", BASE_URL))
.get(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -242,7 +245,7 @@ impl LoadTestClient {
let token = self.token.as_ref().ok_or("Not authenticated")?;
let response = self.client
.get(&format!("{}/api/search", BASE_URL))
.get(&format!("{}/api/search", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.query(&[("q", query)])
.send()

View File

@ -18,7 +18,9 @@ use uuid::Uuid;
use readur::models::{CreateUser, LoginRequest, LoginResponse, UserRole};
const BASE_URL: &str = "http://localhost:8000";
fn get_base_url() -> String {
std::env::var("API_URL").unwrap_or_else(|_| "http://localhost:8000".to_string())
}
/// Test client for RBAC scenarios with multiple user contexts
struct RBACTestClient {
@ -88,7 +90,7 @@ impl RBACTestClient {
};
let register_response = self.client
.post(&format!("{}/api/auth/register", BASE_URL))
.post(&format!("{}/api/auth/register", get_base_url()))
.json(&user_data)
.send()
.await?;
@ -104,7 +106,7 @@ impl RBACTestClient {
};
let login_response = self.client
.post(&format!("{}/api/auth/login", BASE_URL))
.post(&format!("{}/api/auth/login", get_base_url()))
.json(&login_data)
.send()
.await?;
@ -117,7 +119,7 @@ impl RBACTestClient {
// Get user info to extract user ID
let me_response = self.client
.get(&format!("{}/api/auth/me", BASE_URL))
.get(&format!("{}/api/auth/me", get_base_url()))
.header("Authorization", format!("Bearer {}", login_result.token))
.send()
.await?;
@ -147,7 +149,7 @@ impl RBACTestClient {
.part("file", part);
let response = self.client
.post(&format!("{}/api/documents", BASE_URL))
.post(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.multipart(form)
.send()
@ -170,7 +172,7 @@ impl RBACTestClient {
}.ok_or("User not set up")?;
let response = self.client
.get(&format!("{}/api/documents", BASE_URL))
.get(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -192,7 +194,7 @@ impl RBACTestClient {
}.ok_or("User not set up")?;
let response = self.client
.get(&format!("{}/api/documents/{}/ocr", BASE_URL, document_id))
.get(&format!("{}/api/documents/{}/ocr", get_base_url(), document_id))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -223,7 +225,7 @@ impl RBACTestClient {
});
let response = self.client
.post(&format!("{}/api/sources", BASE_URL))
.post(&format!("{}/api/sources", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.json(&source_data)
.send()
@ -246,7 +248,7 @@ impl RBACTestClient {
}.ok_or("User not set up")?;
let response = self.client
.get(&format!("{}/api/sources/{}", BASE_URL, source_id))
.get(&format!("{}/api/sources/{}", get_base_url(), source_id))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?;
@ -265,14 +267,14 @@ impl RBACTestClient {
let response = match operation {
AdminOperation::ListUsers => {
self.client
.get(&format!("{}/api/users", BASE_URL))
.get(&format!("{}/api/users", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?
}
AdminOperation::CreateUser => {
self.client
.post(&format!("{}/api/users", BASE_URL))
.post(&format!("{}/api/users", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.json(&json!({
"username": "test_admin_created",
@ -285,21 +287,21 @@ impl RBACTestClient {
}
AdminOperation::GetMetrics => {
self.client
.get(&format!("{}/api/metrics", BASE_URL))
.get(&format!("{}/api/metrics", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?
}
AdminOperation::GetQueueStats => {
self.client
.get(&format!("{}/api/queue/stats", BASE_URL))
.get(&format!("{}/api/queue/stats", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?
}
AdminOperation::RequeueFailedJobs => {
self.client
.post(&format!("{}/api/queue/requeue-failed", BASE_URL))
.post(&format!("{}/api/queue/requeue-failed", get_base_url()))
.header("Authorization", format!("Bearer {}", token))
.send()
.await?
@ -318,7 +320,7 @@ impl RBACTestClient {
}.ok_or("User not set up")?;
let response = self.client
.put(&format!("{}/api/users/{}", BASE_URL, target_user_id))
.put(&format!("{}/api/users/{}", get_base_url(), target_user_id))
.header("Authorization", format!("Bearer {}", token))
.json(&json!({
"username": "modified_user",
@ -625,7 +627,7 @@ async fn test_privilege_escalation_prevention() {
let user1_token = client.user1_token.as_ref().unwrap();
let create_admin_attempt = client.client
.post(&format!("{}/api/users", BASE_URL))
.post(&format!("{}/api/users", get_base_url()))
.header("Authorization", format!("Bearer {}", user1_token))
.json(&json!({
"username": "malicious_admin",
@ -650,7 +652,7 @@ async fn test_privilege_escalation_prevention() {
// This would typically be done through updating own user profile
// The exact endpoint depends on the API design
let self_promotion_attempt = client.client
.put(&format!("{}/api/users/{}", BASE_URL, user1_id))
.put(&format!("{}/api/users/{}", get_base_url(), user1_id))
.header("Authorization", format!("Bearer {}", user1_token))
.json(&json!({
"username": "user1_promoted",
@ -732,7 +734,7 @@ async fn test_data_visibility_boundaries() {
// Test search isolation (if available)
let search_response = client.client
.get(&format!("{}/api/search", BASE_URL))
.get(&format!("{}/api/search", get_base_url()))
.header("Authorization", format!("Bearer {}", client.user1_token.as_ref().unwrap()))
.query(&[("q", "confidential")])
.send()
@ -802,7 +804,7 @@ async fn test_token_and_session_security() {
for invalid_token in invalid_tokens {
let response = client.client
.get(&format!("{}/api/documents", BASE_URL))
.get(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", invalid_token))
.send()
.await
@ -831,7 +833,7 @@ async fn test_token_and_session_security() {
// Try to access User1's document with User2's token
let cross_token_access = client.client
.get(&format!("{}/api/documents/{}/ocr", BASE_URL, user1_doc_id))
.get(&format!("{}/api/documents/{}/ocr", get_base_url(), user1_doc_id))
.header("Authorization", format!("Bearer {}", user2_token))
.send()
.await
@ -850,7 +852,7 @@ async fn test_token_and_session_security() {
let malformed_jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.malformed_signature";
let malformed_response = client.client
.get(&format!("{}/api/documents", BASE_URL))
.get(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", malformed_jwt))
.send()
.await
@ -865,7 +867,7 @@ async fn test_token_and_session_security() {
println!("🔍 Testing missing authorization...");
let no_auth_response = client.client
.get(&format!("{}/api/documents", BASE_URL))
.get(&format!("{}/api/documents", get_base_url()))
.send()
.await
.expect("No auth request should complete");

View File

@ -11,7 +11,9 @@ use futures;
use readur::models::{DocumentResponse, CreateUser, LoginRequest, LoginResponse};
const BASE_URL: &str = "http://localhost:8000";
fn get_base_url() -> String {
std::env::var("API_URL").unwrap_or_else(|_| "http://localhost:8000".to_string())
}
const TIMEOUT: Duration = Duration::from_secs(120);
struct StressTester {
@ -24,7 +26,7 @@ impl StressTester {
let client = Client::new();
// Check server health
client.get(&format!("{}/api/health", BASE_URL))
client.get(&format!("{}/api/health", get_base_url()))
.timeout(Duration::from_secs(5))
.send()
.await
@ -46,7 +48,7 @@ impl StressTester {
role: Some(readur::models::UserRole::User),
};
client.post(&format!("{}/api/auth/register", BASE_URL))
client.post(&format!("{}/api/auth/register", get_base_url()))
.json(&user_data)
.send()
.await
@ -59,7 +61,7 @@ impl StressTester {
};
let login_response = client
.post(&format!("{}/api/auth/login", BASE_URL))
.post(&format!("{}/api/auth/login", get_base_url()))
.json(&login_data)
.send()
.await
@ -81,7 +83,7 @@ impl StressTester {
let form = reqwest::multipart::Form::new().part("file", part);
let response = self.client
.post(&format!("{}/api/documents", BASE_URL))
.post(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", self.token))
.multipart(form)
.send()
@ -121,7 +123,7 @@ impl StressTester {
async fn get_all_documents(&self) -> Vec<Value> {
let response = self.client
.get(&format!("{}/api/documents", BASE_URL))
.get(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", self.token))
.send()
.await

View File

@ -11,7 +11,9 @@ use futures;
use readur::models::{DocumentResponse, CreateUser, LoginRequest, LoginResponse};
const BASE_URL: &str = "http://localhost:8000";
fn get_base_url() -> String {
std::env::var("API_URL").unwrap_or_else(|_| "http://localhost:8000".to_string())
}
const TIMEOUT: Duration = Duration::from_secs(180);
struct SimpleStressTester {
@ -25,7 +27,7 @@ impl SimpleStressTester {
// Check server health
let response = client
.get(&format!("{}/api/health", BASE_URL))
.get(&format!("{}/api/health", get_base_url()))
.timeout(Duration::from_secs(5))
.send()
.await
@ -52,7 +54,7 @@ impl SimpleStressTester {
};
let register_response = client
.post(&format!("{}/api/auth/register", BASE_URL))
.post(&format!("{}/api/auth/register", get_base_url()))
.json(&user_data)
.send()
.await
@ -69,7 +71,7 @@ impl SimpleStressTester {
};
let login_response = client
.post(&format!("{}/api/auth/login", BASE_URL))
.post(&format!("{}/api/auth/login", get_base_url()))
.json(&login_data)
.send()
.await
@ -95,7 +97,7 @@ impl SimpleStressTester {
let form = reqwest::multipart::Form::new().part("file", part);
let response = self.client
.post(&format!("{}/api/documents", BASE_URL))
.post(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", self.token))
.multipart(form)
.send()
@ -149,7 +151,7 @@ impl SimpleStressTester {
async fn get_all_documents(&self) -> Vec<Value> {
let response = self.client
.get(&format!("{}/api/documents", BASE_URL))
.get(&format!("{}/api/documents", get_base_url()))
.header("Authorization", format!("Bearer {}", self.token))
.send()
.await