Files
ElyOffice/crates/ely-mail-engine/tests/store_release.rs
T
ZacharyZhang-NYandClaude Opus 5.5 7c5bf48589 C12.3: ElyMail local store
SQLite index, content-addressed originals, rebuildable FTS5 search,
schema versions with a backup before each upgrade and read-only on
failure, and size reporting. Three review rounds; the round 3 fixes
are checked by tests, not reviewed again.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 18:14:09 -04:00

73 lines
2.4 KiB
Rust

#![cfg(windows)]
use std::{fs::File, os::windows::fs::OpenOptionsExt, path::Path};
use ely_mail_engine::{Fetched, Key, MailboxId, Store};
use sha2::{Digest, Sha256};
const ONE: &[u8] = b"Subject: one\r\n\r\nfirst body\r\n";
const TWO: &[u8] = b"Subject: two\r\n\r\nsecond body\r\n";
fn inbox(dir: &Path) -> (Store, MailboxId) {
let store = Store::open(dir).unwrap();
let account = store.add_account("ann@example.com").unwrap();
let inbox = store.mailbox(account, "INBOX").unwrap();
(store, inbox)
}
fn imap() -> Key {
Key::Imap {
uidvalidity: 1,
uid: 1,
}
}
fn original_path(dir: &Path, raw: &[u8]) -> std::path::PathBuf {
let hash: String = Sha256::digest(raw)
.iter()
.map(|byte| format!("{byte:02x}"))
.collect();
dir.join("content").join(&hash[..2]).join(hash)
}
/// Read sharing only: delete fails.
fn hold(path: &Path) -> File {
File::options().read(true).share_mode(1).open(path).unwrap()
}
#[test]
fn a_held_original_keeps_its_message_for_retry() {
let dir = tempfile::tempdir().unwrap();
let (mut store, inbox) = inbox(dir.path());
let id = store.put(inbox, &imap(), &[], Fetched::Whole(ONE)).unwrap();
let path = original_path(dir.path(), ONE);
let held = hold(&path);
assert!(store.remove(id).is_err());
assert_eq!(store.get(id).unwrap().subject.as_deref(), Some("one"));
assert_eq!(store.original(id).unwrap().as_deref(), Some(ONE));
drop(held);
store.remove(id).unwrap();
assert!(store.get(id).is_err());
assert!(!path.exists());
assert_eq!(store.sizes().unwrap().originals, 0);
}
#[test]
fn a_held_old_original_keeps_the_old_message() {
let dir = tempfile::tempdir().unwrap();
let (mut store, inbox) = inbox(dir.path());
let id = store.put(inbox, &imap(), &[], Fetched::Whole(ONE)).unwrap();
let old = original_path(dir.path(), ONE);
let new = original_path(dir.path(), TWO);
let held = hold(&old);
assert!(store.put(inbox, &imap(), &[], Fetched::Whole(TWO)).is_err());
assert_eq!(store.get(id).unwrap().subject.as_deref(), Some("one"));
assert_eq!(store.original(id).unwrap().as_deref(), Some(ONE));
assert!(!new.exists());
drop(held);
store.put(inbox, &imap(), &[], Fetched::Whole(TWO)).unwrap();
assert_eq!(store.original(id).unwrap().as_deref(), Some(TWO));
assert!(!old.exists());
assert_eq!(store.sizes().unwrap().originals, TWO.len() as u64);
}