mirror of
https://github.com/readur/readur.git
synced 2026-01-13 10:09:48 -06:00
182 lines
7.6 KiB
Rust
182 lines
7.6 KiB
Rust
use readur::{
|
|
models::{CreateWebDAVDirectory, User, AuthProvider},
|
|
services::webdav::{SmartSyncService, WebDAVService, WebDAVConfig},
|
|
test_utils::{TestContext, TestAuthHelper},
|
|
};
|
|
|
|
/// Helper function to create test database and user with automatic cleanup
|
|
async fn create_test_setup() -> (TestContext, User) {
|
|
let test_context = TestContext::new().await;
|
|
let auth_helper = TestAuthHelper::new(test_context.app().clone());
|
|
let test_user = auth_helper.create_test_user().await;
|
|
|
|
// Convert TestUser to User model for compatibility
|
|
let user = User {
|
|
id: test_user.user_response.id,
|
|
username: test_user.user_response.username,
|
|
email: test_user.user_response.email,
|
|
password_hash: Some("hashed_password".to_string()),
|
|
role: test_user.user_response.role,
|
|
created_at: chrono::Utc::now(),
|
|
updated_at: chrono::Utc::now(),
|
|
oidc_subject: None,
|
|
oidc_issuer: None,
|
|
oidc_email: None,
|
|
auth_provider: AuthProvider::Local,
|
|
};
|
|
|
|
(test_context, user)
|
|
}
|
|
|
|
/// Helper function to create WebDAV service for testing
|
|
fn create_test_webdav_service() -> WebDAVService {
|
|
let config = WebDAVConfig {
|
|
server_url: "https://test.example.com".to_string(),
|
|
username: "test".to_string(),
|
|
password: "test".to_string(),
|
|
watch_folders: vec!["/Documents".to_string()],
|
|
file_extensions: vec!["pdf".to_string(), "txt".to_string()],
|
|
timeout_seconds: 30,
|
|
server_type: Some("generic".to_string()),
|
|
};
|
|
|
|
WebDAVService::new(config).expect("Failed to create WebDAV service")
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_smart_sync_no_changes_skip() {
|
|
// Integration Test: Smart sync with no directory changes should skip sync entirely
|
|
// Expected: Should return SkipSync when all directory ETags are unchanged
|
|
|
|
let (test_context, user) = create_test_setup().await;
|
|
let state = test_context.state().clone();
|
|
let smart_sync_service = SmartSyncService::new(state.clone());
|
|
|
|
// Pre-populate database with known directory ETags
|
|
let known_directories = vec![
|
|
CreateWebDAVDirectory {
|
|
user_id: user.id,
|
|
directory_path: "/Documents".to_string(),
|
|
directory_etag: "root-etag-unchanged".to_string(),
|
|
file_count: 8,
|
|
total_size_bytes: 800000,
|
|
},
|
|
CreateWebDAVDirectory {
|
|
user_id: user.id,
|
|
directory_path: "/Documents/Projects".to_string(),
|
|
directory_etag: "projects-etag-unchanged".to_string(),
|
|
file_count: 12,
|
|
total_size_bytes: 1200000,
|
|
},
|
|
CreateWebDAVDirectory {
|
|
user_id: user.id,
|
|
directory_path: "/Documents/Archive".to_string(),
|
|
directory_etag: "archive-etag-unchanged".to_string(),
|
|
file_count: 25,
|
|
total_size_bytes: 2500000,
|
|
},
|
|
];
|
|
|
|
for dir in &known_directories {
|
|
state.db.create_or_update_webdav_directory(dir).await
|
|
.expect("Failed to create directory tracking");
|
|
}
|
|
|
|
// Verify known directories were created
|
|
let stored_dirs = state.db.list_webdav_directories(user.id).await.unwrap();
|
|
assert_eq!(stored_dirs.len(), 3, "Should have 3 known directories");
|
|
|
|
// In a real scenario, WebDAV would return the same ETags, indicating no changes
|
|
// Since we can't mock the WebDAV service easily, we test the database logic
|
|
|
|
// Test bulk directory fetching (key performance optimization)
|
|
let start_time = std::time::Instant::now();
|
|
let fetched_dirs = state.db.list_webdav_directories(user.id).await.unwrap();
|
|
let fetch_duration = start_time.elapsed();
|
|
|
|
assert!(fetch_duration.as_millis() < 50, "Bulk directory fetch should be fast");
|
|
assert_eq!(fetched_dirs.len(), 3, "Should fetch all directories efficiently");
|
|
|
|
// Verify directory data integrity
|
|
let docs_dir = fetched_dirs.iter().find(|d| d.directory_path == "/Documents").unwrap();
|
|
assert_eq!(docs_dir.directory_etag, "root-etag-unchanged");
|
|
assert_eq!(docs_dir.file_count, 8);
|
|
|
|
let projects_dir = fetched_dirs.iter().find(|d| d.directory_path == "/Documents/Projects").unwrap();
|
|
assert_eq!(projects_dir.directory_etag, "projects-etag-unchanged");
|
|
assert_eq!(projects_dir.file_count, 12);
|
|
|
|
let archive_dir = fetched_dirs.iter().find(|d| d.directory_path == "/Documents/Archive").unwrap();
|
|
assert_eq!(archive_dir.directory_etag, "archive-etag-unchanged");
|
|
assert_eq!(archive_dir.file_count, 25);
|
|
|
|
println!("✅ No changes sync test completed successfully - bulk fetch in {:?}", fetch_duration);
|
|
|
|
// Clean up test context
|
|
if let Err(e) = test_context.cleanup_and_close().await {
|
|
eprintln!("Warning: Test cleanup failed: {}", e);
|
|
}
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_directory_etag_comparison_efficiency() {
|
|
// Integration Test: Directory ETag comparison should be efficient for large numbers of directories
|
|
// This tests the bulk fetching performance optimization
|
|
|
|
let (test_context, user) = create_test_setup().await;
|
|
let state = test_context.state().clone();
|
|
|
|
// Create a larger number of directories to test performance
|
|
let num_directories = 100;
|
|
let mut directories = Vec::new();
|
|
|
|
for i in 0..num_directories {
|
|
directories.push(CreateWebDAVDirectory {
|
|
user_id: user.id,
|
|
directory_path: format!("/Documents/Folder{:03}", i),
|
|
directory_etag: format!("etag-folder-{:03}", i),
|
|
file_count: i as i64 % 10 + 1, // 1-10 files per directory
|
|
total_size_bytes: (i as i64 + 1) * 10000, // Varying sizes
|
|
});
|
|
}
|
|
|
|
// Batch insert directories
|
|
let insert_start = std::time::Instant::now();
|
|
for dir in &directories {
|
|
state.db.create_or_update_webdav_directory(dir).await
|
|
.expect("Failed to create directory");
|
|
}
|
|
let insert_duration = insert_start.elapsed();
|
|
|
|
// Test bulk fetch performance
|
|
let fetch_start = std::time::Instant::now();
|
|
let fetched_dirs = state.db.list_webdav_directories(user.id).await.unwrap();
|
|
let fetch_duration = fetch_start.elapsed();
|
|
|
|
// Verify all directories were created and fetched
|
|
assert_eq!(fetched_dirs.len(), num_directories, "Should fetch all {} directories", num_directories);
|
|
|
|
// Performance assertions
|
|
assert!(fetch_duration.as_millis() < 200, "Bulk fetch of {} directories should be under 200ms, got {:?}", num_directories, fetch_duration);
|
|
assert!(insert_duration.as_millis() < 5000, "Bulk insert of {} directories should be under 5s, got {:?}", num_directories, insert_duration);
|
|
|
|
// Verify data integrity on a few random directories
|
|
let dir_50 = fetched_dirs.iter().find(|d| d.directory_path == "/Documents/Folder050").unwrap();
|
|
assert_eq!(dir_50.directory_etag, "etag-folder-050");
|
|
assert_eq!(dir_50.file_count, 1); // 50 % 10 + 1 = 1
|
|
assert_eq!(dir_50.total_size_bytes, 510000); // (50 + 1) * 10000
|
|
|
|
let dir_99 = fetched_dirs.iter().find(|d| d.directory_path == "/Documents/Folder099").unwrap();
|
|
assert_eq!(dir_99.directory_etag, "etag-folder-099");
|
|
assert_eq!(dir_99.file_count, 10); // 99 % 10 + 1 = 10
|
|
assert_eq!(dir_99.total_size_bytes, 1000000); // (99 + 1) * 10000
|
|
|
|
println!("✅ Directory ETag comparison efficiency test completed successfully");
|
|
println!(" Created {} directories in {:?}", num_directories, insert_duration);
|
|
println!(" Fetched {} directories in {:?}", num_directories, fetch_duration);
|
|
|
|
// Clean up test context
|
|
if let Err(e) = test_context.cleanup_and_close().await {
|
|
eprintln!("Warning: Test cleanup failed: {}", e);
|
|
}
|
|
} |