use assert_cmd::prelude::*; use std::env; use std::process::Command; // ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗ // ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝ // ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗ // ██╔═══╝ ██╔══██║╚════██║╚════██║██║██║╚██╗██║██║ ██║ // ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝ // ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ #[test] fn passing_print_version() -> Result<(), Box> { let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; let out = cmd.arg("-V").output().unwrap(); // STDOUT should contain program name and version assert_eq!( std::str::from_utf8(&out.stdout).unwrap(), format!("{} {}\n", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION")) ); // STDERR should be empty assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), ""); // The exit code should be 0 out.assert().code(0); Ok(()) } #[test] fn passing_bad_input_empty_target() -> Result<(), Box> { let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; let out = cmd.arg("").output().unwrap(); // STDOUT should be empty assert_eq!(std::str::from_utf8(&out.stdout).unwrap(), ""); // STDERR should contain error description assert_eq!( std::str::from_utf8(&out.stderr).unwrap(), "No target specified\n" ); // The exit code should be 1 out.assert().code(1); Ok(()) } #[test] fn passing_bad_input_data_url() -> Result<(), Box> { let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; let out = cmd.arg("data:,Hello%2C%20World!").output().unwrap(); // STDOUT should contain HTML assert_eq!(std::str::from_utf8(&out.stdout).unwrap(), ""); // STDERR should contain error description assert_eq!( std::str::from_utf8(&out.stderr).unwrap(), "Unsupported data URL input\n" ); // The exit code should be 1 out.assert().code(1); Ok(()) } #[test] fn passing_isolate_data_url() -> Result<(), Box> { let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; let out = cmd .arg("-I") .arg("data:text/html,Hello%2C%20World!") .output() .unwrap(); // STDOUT should contain isolated HTML assert_eq!( std::str::from_utf8(&out.stdout).unwrap(), "\ \ Hello, World!\n" ); // STDERR should be empty assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), ""); // The exit code should be 0 out.assert().code(0); Ok(()) } #[test] fn passing_remove_css_from_data_url() -> Result<(), Box> { let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; let out = cmd .arg("-c") .arg("data:text/html,Hello") .output() .unwrap(); // STDOUT should contain HTML with no CSS assert_eq!( std::str::from_utf8(&out.stdout).unwrap(), "\ \ \ Hello\n" ); // STDERR should be empty assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), ""); // The exit code should be 0 out.assert().code(0); Ok(()) } #[test] fn passing_remove_frames_from_data_url() -> Result<(), Box> { let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; let out = cmd .arg("-f") .arg("data:text/html,Hi") .output() .unwrap(); // STDOUT should contain HTML with no iframes assert_eq!( std::str::from_utf8(&out.stdout).unwrap(), "\ \ Hi\n" ); // STDERR should be empty assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), ""); // The exit code should be 0 out.assert().code(0); Ok(()) } #[test] fn passing_remove_images_from_data_url() -> Result<(), Box> { let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; let out = cmd .arg("-i") .arg("data:text/html,Hi") .output() .unwrap(); // STDOUT should contain HTML with no images assert_eq!( std::str::from_utf8(&out.stdout).unwrap(), "\ \ \ \ \ \ Hi\ \ \n" ); // STDERR should be empty assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), ""); // The exit code should be 0 out.assert().code(0); Ok(()) } #[test] fn passing_remove_js_from_data_url() -> Result<(), Box> { let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; let out = cmd .arg("-j") .arg("data:text/html,Hi") .output() .unwrap(); // STDOUT should contain HTML with no JS assert_eq!( std::str::from_utf8(&out.stdout).unwrap(), "\ \ \ \ Hi\ \n" ); // STDERR should be empty assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), ""); // The exit code should be 0 out.assert().code(0); Ok(()) } #[test] fn passing_local_file_target_input() -> Result<(), Box> { let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; let cwd_normalized: String = str!(env::current_dir().unwrap().to_str().unwrap()).replace("\\", "/"); let out = cmd .arg(if cfg!(windows) { "src\\tests\\data\\local-file.html" } else { "src/tests/data/local-file.html" }) .output() .unwrap(); let file_url_protocol: &str = if cfg!(windows) { "file:///" } else { "file://" }; // STDOUT should contain HTML from the local file assert_eq!( std::str::from_utf8(&out.stdout).unwrap(), "\n \ \n \ Local HTML file\n \ \n \ \n\n\n\n \ \"\"\n \ Tricky href\n \ Remote URL\n \ \n\n\n\n\ \n" ); // STDERR should contain list of retrieved file URLs assert_eq!( std::str::from_utf8(&out.stderr).unwrap(), format!( "{file}{cwd}/src/tests/data/local-file.html\n\ {file}{cwd}/src/tests/data/local-style.css\n\ {file}{cwd}/src/tests/data/local-script.js\n", file = file_url_protocol, cwd = cwd_normalized ) ); // The exit code should be 0 out.assert().code(0); Ok(()) } #[test] fn passing_local_file_target_input_absolute_target_path() -> Result<(), Box> { let cwd = env::current_dir().unwrap(); let cwd_normalized: String = str!(env::current_dir().unwrap().to_str().unwrap()).replace("\\", "/"); let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; let out = cmd .arg("-jciI") .arg(if cfg!(windows) { format!( "{cwd}\\src\\tests\\data\\local-file.html", cwd = cwd.to_str().unwrap() ) } else { format!( "{cwd}/src/tests/data/local-file.html", cwd = cwd.to_str().unwrap() ) }) .output() .unwrap(); let file_url_protocol: &str = if cfg!(windows) { "file:///" } else { "file://" }; // STDOUT should contain HTML from the local file assert_eq!( std::str::from_utf8(&out.stdout).unwrap(), "\ \n \ \n \ Local HTML file\n \ \n \ \n\n\n\n \ \"\"\n \ Tricky href\n \ Remote URL\n \ \n\n\n\n\ \n" ); // STDERR should contain only the target file assert_eq!( std::str::from_utf8(&out.stderr).unwrap(), format!( "{file}{cwd}/src/tests/data/local-file.html\n", file = file_url_protocol, cwd = cwd_normalized, ) ); // The exit code should be 0 out.assert().code(0); Ok(()) } #[test] fn passing_local_file_url_target_input() -> Result<(), Box> { let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; let cwd = env::current_dir().unwrap(); let file_url_protocol: &str = if cfg!(windows) { "file:///" } else { "file://" }; let out = cmd .arg("-cji") .arg(if cfg!(windows) { format!( "{file}{cwd}\\src\\tests\\data\\local-file.html", file = file_url_protocol, cwd = cwd.to_str().unwrap(), ) } else { format!( "{file}{cwd}/src/tests/data/local-file.html", file = file_url_protocol, cwd = cwd.to_str().unwrap(), ) }) .output() .unwrap(); // STDOUT should contain HTML from the local file assert_eq!( std::str::from_utf8(&out.stdout).unwrap(), "\ \n \ \n \ Local HTML file\n \ \n \ \n\n\n\n \ \"\"\n \ Tricky href\n \ Remote URL\n \ \n\n\n\n\ \n" ); // STDERR should contain list of retrieved file URLs assert_eq!( std::str::from_utf8(&out.stderr).unwrap(), if cfg!(windows) { format!( "{file}{cwd}\\src\\tests\\data\\local-file.html\n", file = file_url_protocol, cwd = cwd.to_str().unwrap(), ) } else { format!( "{file}{cwd}/src/tests/data/local-file.html\n", file = file_url_protocol, cwd = cwd.to_str().unwrap(), ) } ); // The exit code should be 0 out.assert().code(0); Ok(()) } #[test] fn passing_security_disallow_local_assets_within_data_url_targets( ) -> Result<(), Box> { let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; let out = cmd .arg("data:text/html,%3Cscript%20src=\"src/tests/data/local-script.js\"%3E%3C/script%3E") .output() .unwrap(); // STDOUT should contain HTML with no JS in it assert_eq!( std::str::from_utf8(&out.stdout).unwrap(), "\n" ); // STDERR should be empty assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), ""); // The exit code should be 0 out.assert().code(0); Ok(()) }