// Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html #![cfg(test)] use std::path::Path; use tempfile::tempdir; use crate::{ collection::CollectionBuilder, import_export::package::import_colpkg, io::{create_dir, create_dir_all, read_file}, media::MediaManager, prelude::*, }; fn collection_with_media(dir: &Path, name: &str) -> Result { let name = format!("{name}_src"); let media_folder = dir.join(format!("{name}.media")); create_dir(&media_folder)?; // add collection with sentinel note let mut col = CollectionBuilder::new(dir.join(format!("{name}.anki2"))) .set_media_paths(media_folder, dir.join(format!("{name}.mdb"))) .build()?; let nt = col.get_notetype_by_name("Basic")?.unwrap(); let mut note = nt.new_note(); col.add_note(&mut note, DeckId(1))?; // add sample media let mgr = col.media()?; mgr.add_file("1", b"1")?; mgr.add_file("2", b"2")?; mgr.add_file("3", b"3")?; Ok(col) } #[test] fn roundtrip() -> Result<()> { let _dir = tempdir()?; let dir = _dir.path(); for (legacy, name) in [(true, "legacy"), (false, "v3")] { // export to a file let col = collection_with_media(dir, name)?; let colpkg_name = dir.join(format!("{name}.colpkg")); col.export_colpkg(&colpkg_name, true, legacy, |_, _| true)?; // import into a new collection let anki2_name = dir .join(format!("{name}.anki2")) .to_string_lossy() .into_owned(); let import_media_dir = dir.join(format!("{name}.media")); create_dir_all(&import_media_dir)?; let import_media_db = dir.join(format!("{name}.mdb")); MediaManager::new(&import_media_dir, &import_media_db)?; import_colpkg( &colpkg_name.to_string_lossy(), &anki2_name, &import_media_dir, &import_media_db, |_, _| true, )?; // confirm collection imported let col = CollectionBuilder::new(&anki2_name).build()?; assert_eq!( col.storage.db_scalar::("select count() from notes")?, 1 ); // confirm media imported correctly assert_eq!(read_file(import_media_dir.join("1"))?, b"1"); assert_eq!(read_file(import_media_dir.join("2"))?, b"2"); assert_eq!(read_file(import_media_dir.join("3"))?, b"3"); } Ok(()) } /// Files with an invalid encoding should prevent export, except /// on Apple platforms where the encoding is transparently changed. #[test] #[cfg(not(target_vendor = "apple"))] fn normalization_check_on_export() -> Result<()> { use crate::io::write_file; let _dir = tempdir()?; let dir = _dir.path(); let col = collection_with_media(dir, "normalize")?; let colpkg_name = dir.join("normalize.colpkg"); // manually write a file in the wrong encoding. write_file(col.media_folder.join("ぱぱ.jpg"), "nfd encoding")?; assert_eq!( col.export_colpkg(&colpkg_name, true, false, |_, _| true,) .unwrap_err(), AnkiError::MediaCheckRequired ); // file should have been cleaned up assert!(!colpkg_name.exists()); Ok(()) }