Files
Curator/tests/ui.rs
T

237 lines
6.8 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! End-to-end UI tests: drive the egui window headlessly (egui_kittest) the way
//! a user would — open a dialog, click buttons — and check the pool on disk.
use std::fs;
use std::path::{Path, PathBuf};
use std::time::{Duration, Instant};
use curator::core::file_manager::FileManager;
use curator::ui::app::CuratorApp;
use egui_kittest::Harness;
use egui_kittest::kittest::Queryable;
struct Env {
dir: tempfile::TempDir,
}
impl Env {
fn new() -> Self {
Self {
dir: tempfile::tempdir().unwrap(),
}
}
fn pool(&self) -> PathBuf {
self.dir.path().join("pool")
}
fn manager(&self) -> FileManager {
let mut fm = FileManager::with_config_path(self.dir.path().join("cfg.json"));
fm.set_pool_dir(&self.pool()).unwrap();
fm.load_pool_movies().unwrap();
fm
}
fn source(&self, name: &str) -> PathBuf {
let p = self.dir.path().join("src").join(name);
fs::create_dir_all(p.parent().unwrap()).unwrap();
fs::write(&p, name).unwrap();
p
}
}
fn harness(fm: FileManager) -> Harness<'static, CuratorApp> {
Harness::builder()
.with_size(egui::vec2(1300.0, 800.0))
.allow_missing_glyphs()
.with_accessibility_check(false)
.build_eframe(|cc| CuratorApp::new(fm, cc.egui_ctx.clone()))
}
/// Step until no background task runs (or time out).
fn wait_idle(h: &mut Harness<'static, CuratorApp>) {
let start = Instant::now();
loop {
h.step();
if !h.state().busy() {
h.run_steps(3);
return;
}
assert!(
start.elapsed() < Duration::from_secs(20),
"task did not finish"
);
std::thread::sleep(Duration::from_millis(20));
}
}
fn exists(p: &Path) -> bool {
p.exists()
}
#[test]
fn test_import_movie_through_the_dialog() {
let env = Env::new();
let src = env.source("Matrix.1999.1080p.mkv");
let mut h = harness(env.manager());
h.state_mut().open_import(vec![src.clone()]);
h.run_steps(3);
h.get_by_label("OK").click();
h.run_steps(2);
wait_idle(&mut h);
let pooled = env.pool().join("Filmy/Matrix.1999.1080p (1999).mkv");
assert!(
exists(&pooled),
"pool: {:?}",
fs::read_dir(env.pool().join("Filmy"))
.unwrap()
.collect::<Vec<_>>()
);
assert!(exists(&src), "copy keeps the source");
// the summary message is shown and can be dismissed
h.get_by_label("OK").click();
h.run_steps(2);
let fm = h.state().file_manager().unwrap();
assert_eq!(fm.filelist.len(), 1);
}
#[test]
fn test_import_requires_a_year() {
let env = Env::new();
let src = env.source("Bez roku.mkv");
let mut h = harness(env.manager());
h.state_mut().open_import(vec![src]);
h.run_steps(3);
h.get_by_label("OK").click();
h.run_steps(3);
// a warning appears and nothing is imported
assert!(h.query_by_label_contains("čtyřmístný rok").is_some());
assert!(
fs::read_dir(env.pool().join("Filmy"))
.unwrap()
.next()
.is_none()
);
}
#[test]
fn test_import_existing_film_as_a_version() {
let env = Env::new();
let mut fm = env.manager();
let opts = curator::core::file_manager::ImportOptions {
year: Some("2009".into()),
tmdb_id: Some("19995".into()),
..Default::default()
};
fm.import_movie(&env.source("a.mkv"), "Avatar", opts)
.unwrap();
// a second copy of the same film, named so title/year/id are prefilled
let src = env.source("Avatar (2009).3D.HSBS.mkv");
let nfo = src.with_extension("nfo");
fs::write(
&nfo,
"<movie><title>Avatar</title><uniqueid type=\"tmdb\">19995</uniqueid></movie>",
)
.unwrap();
let mut h = harness(fm);
h.state_mut().open_import(vec![src]);
h.run_steps(3);
h.get_by_label("OK").click();
h.run_steps(3);
// conflict question → add as a version
h.get_by_label("Přidat jako verzi").click();
h.run_steps(3);
// the popisek prompt is pre-filled from the 3D tag
h.get_by_label("OK").click();
h.run_steps(2);
wait_idle(&mut h);
let folder = env.pool().join("Filmy/Avatar (2009) [tmdbid-19995]");
assert!(folder.join("Avatar (2009) [tmdbid-19995].mkv").exists());
assert!(
folder
.join("Avatar (2009) [tmdbid-19995] - 3D HSBS.mkv")
.exists()
);
}
fn imported(env: &Env, fm: &mut FileManager, name: &str, title: &str) -> PathBuf {
fm.import_movie(
&env.source(name),
title,
curator::core::file_manager::ImportOptions::default(),
)
.unwrap()
.unwrap()
}
#[test]
fn test_edit_movie_renames_with_year_and_id() {
let env = Env::new();
let mut fm = env.manager();
let p = imported(&env, &mut fm, "x.mkv", "Matrix");
let mut h = harness(fm);
h.state_mut().select_movies(&[p]);
h.state_mut().debug_action("edit");
h.run_steps(3);
// the editor's year and TMDb fields (hint texts identify them)
for (label, text) in [("Rok:", "1999"), ("TMDb ID:", "603")] {
h.get_by_label(label).focus();
h.run_steps(1);
h.get_by_label(label).type_text(text);
h.run_steps(1);
}
h.run_steps(2);
h.get_by_label("OK").click();
h.run_steps(3);
assert!(
env.pool()
.join("Filmy/Matrix (1999) [tmdbid-603].mkv")
.exists()
);
}
#[test]
fn test_remove_movie_after_confirmation() {
let env = Env::new();
let mut fm = env.manager();
let p = imported(&env, &mut fm, "x.mkv", "Matrix");
let mut h = harness(fm);
h.state_mut().select_movies(std::slice::from_ref(&p));
h.run_steps(2);
h.key_press(egui::Key::Delete);
h.run_steps(3);
h.get_by_label("Ano").click();
h.run_steps(3);
assert!(!p.exists());
assert!(h.state().file_manager().unwrap().filelist.is_empty());
}
#[test]
fn test_assign_a_new_tag_through_the_dialog() {
let env = Env::new();
let mut fm = env.manager();
let p = imported(&env, &mut fm, "x.mkv", "Matrix");
let mut h = harness(fm);
h.state_mut().select_movies(std::slice::from_ref(&p));
h.state_mut().debug_action("tags");
h.run_steps(3);
h.get_by_label("➕ Nový štítek…").click();
h.run_steps(3);
// pick the "Žánr" category, then type the tag name
h.get_all_by_label("Žánr").last().unwrap().click();
h.run_steps(2);
h.get_all_by_label("OK").last().unwrap().click();
h.run_steps(3);
h.get_all_by_role(egui::accesskit::Role::TextInput)
.last()
.unwrap()
.type_text("Sci-Fi");
h.run_steps(2);
h.get_all_by_label("OK").last().unwrap().click();
h.run_steps(3);
h.get_by_label("OK").click();
h.run_steps(3);
let f = h.state().file_manager().unwrap().file(&p).unwrap().clone();
assert!(f.tag_paths().contains("Žánr/Sci-Fi"), "{:?}", f.tags);
}