mod common;
use common::{
engine_for_mock, mock_action, mock_action_any, mock_anki_response, setup_mock_server,
};
#[tokio::test]
async fn test_backup_deck() {
let server = setup_mock_server().await;
mock_action(&server, "exportPackage", mock_anki_response(true)).await;
let engine = engine_for_mock(&server);
let temp_dir = tempfile::tempdir().unwrap();
let result = engine
.backup()
.backup_deck("Japanese", temp_dir.path())
.await;
assert!(result.is_err() || result.is_ok());
}
#[tokio::test]
async fn test_restore_deck() {
let server = setup_mock_server().await;
let temp_dir = tempfile::tempdir().unwrap();
let backup_path = temp_dir.path().join("test.apkg");
std::fs::write(&backup_path, b"dummy apkg content").unwrap();
mock_action(&server, "importPackage", mock_anki_response(true)).await;
let engine = engine_for_mock(&server);
let result = engine.backup().restore_deck(&backup_path).await;
assert!(result.is_ok());
let restore_result = result.unwrap();
assert!(restore_result.success);
}
#[tokio::test]
async fn test_restore_deck_not_found() {
let server = setup_mock_server().await;
let engine = engine_for_mock(&server);
let result = engine
.backup()
.restore_deck("/nonexistent/path/backup.apkg")
.await;
assert!(result.is_err());
let err = result.unwrap_err();
assert!(err.to_string().contains("not found"));
}
#[tokio::test]
async fn test_list_backups() {
let server = setup_mock_server().await;
let engine = engine_for_mock(&server);
let temp_dir = tempfile::tempdir().unwrap();
std::fs::write(temp_dir.path().join("backup1.apkg"), b"content1").unwrap();
std::fs::write(temp_dir.path().join("backup2.apkg"), b"content2").unwrap();
std::fs::write(temp_dir.path().join("not-a-backup.txt"), b"text").unwrap();
let backups = engine.backup().list_backups(temp_dir.path()).await.unwrap();
assert_eq!(backups.len(), 2);
assert!(
backups
.iter()
.all(|b| b.path.extension().unwrap() == "apkg")
);
}
#[tokio::test]
async fn test_list_backups_empty_dir() {
let server = setup_mock_server().await;
let engine = engine_for_mock(&server);
let temp_dir = tempfile::tempdir().unwrap();
let backups = engine.backup().list_backups(temp_dir.path()).await.unwrap();
assert!(backups.is_empty());
}
#[tokio::test]
async fn test_list_backups_nonexistent_dir() {
let server = setup_mock_server().await;
let engine = engine_for_mock(&server);
let backups = engine
.backup()
.list_backups("/nonexistent/directory")
.await
.unwrap();
assert!(backups.is_empty());
}
#[tokio::test]
async fn test_rotate_backups() {
let server = setup_mock_server().await;
let engine = engine_for_mock(&server);
let temp_dir = tempfile::tempdir().unwrap();
for i in 1..=5 {
let path = temp_dir.path().join(format!("backup{}.apkg", i));
std::fs::write(&path, format!("content{}", i)).unwrap();
std::thread::sleep(std::time::Duration::from_millis(10));
}
let deleted = engine
.backup()
.rotate_backups(temp_dir.path(), 2)
.await
.unwrap();
assert_eq!(deleted.len(), 3);
let remaining = engine.backup().list_backups(temp_dir.path()).await.unwrap();
assert_eq!(remaining.len(), 2);
}
#[tokio::test]
async fn test_rotate_backups_keep_all() {
let server = setup_mock_server().await;
let engine = engine_for_mock(&server);
let temp_dir = tempfile::tempdir().unwrap();
for i in 1..=3 {
std::fs::write(
temp_dir.path().join(format!("backup{}.apkg", i)),
format!("content{}", i),
)
.unwrap();
}
let deleted = engine
.backup()
.rotate_backups(temp_dir.path(), 5)
.await
.unwrap();
assert!(deleted.is_empty());
let remaining = engine.backup().list_backups(temp_dir.path()).await.unwrap();
assert_eq!(remaining.len(), 3);
}
#[tokio::test]
async fn test_backup_collection() {
let server = setup_mock_server().await;
mock_action(
&server,
"deckNames",
mock_anki_response(vec!["Default", "Japanese"]),
)
.await;
mock_action_any(&server, "exportPackage", mock_anki_response(true)).await;
let engine = engine_for_mock(&server);
let temp_dir = tempfile::tempdir().unwrap();
let result = engine.backup().backup_collection(temp_dir.path()).await;
assert!(result.is_ok());
let collection_result = result.unwrap();
assert_eq!(collection_result.successful.len(), 2);
assert!(collection_result.failed.is_empty());
}
#[tokio::test]
async fn test_list_backups_recursive() {
let server = setup_mock_server().await;
let engine = engine_for_mock(&server);
let temp_dir = tempfile::tempdir().unwrap();
let subdir = temp_dir.path().join("subdir");
std::fs::create_dir(&subdir).unwrap();
std::fs::write(temp_dir.path().join("root.apkg"), b"root").unwrap();
std::fs::write(subdir.join("nested.apkg"), b"nested").unwrap();
let backups = engine.backup().list_backups(temp_dir.path()).await.unwrap();
assert_eq!(backups.len(), 2);
}