271 lines
12 KiB
Rust
271 lines
12 KiB
Rust
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
|
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
|
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
|
// ██╔═══╝ ██╔══██║╚════██║╚════██║██║██║╚██╗██║██║ ██║
|
|
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
|
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
|
|
|
#[cfg(test)]
|
|
mod passing {
|
|
use assert_cmd::prelude::*;
|
|
use std::env;
|
|
use std::fs;
|
|
use std::path::{Path, MAIN_SEPARATOR};
|
|
use std::process::Command;
|
|
use url::Url;
|
|
|
|
use monolith::url::EMPTY_IMAGE_DATA_URL;
|
|
|
|
#[test]
|
|
fn local_file_target_input_relative_target_path() {
|
|
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap();
|
|
let cwd_normalized: String = env::current_dir()
|
|
.unwrap()
|
|
.to_str()
|
|
.unwrap()
|
|
.replace("\\", "/");
|
|
let out = cmd
|
|
.arg("-M")
|
|
.arg(format!(
|
|
"tests{s}_data_{s}basic{s}local-file.html",
|
|
s = MAIN_SEPARATOR
|
|
))
|
|
.output()
|
|
.unwrap();
|
|
let file_url_protocol: &str = if cfg!(windows) { "file:///" } else { "file://" };
|
|
|
|
// STDERR should contain list of retrieved file URLs, two missing
|
|
assert_eq!(
|
|
String::from_utf8_lossy(&out.stderr),
|
|
format!(
|
|
"\
|
|
{file}{cwd}/tests/_data_/basic/local-file.html\n \
|
|
{file}{cwd}/tests/_data_/basic/local-style.css\n \
|
|
{file}{cwd}/tests/_data_/basic/local-style-does-not-exist.css (not found)\n \
|
|
{file}{cwd}/tests/_data_/basic/monolith.png (not found)\n \
|
|
{file}{cwd}/tests/_data_/basic/local-script.js\n\
|
|
",
|
|
file = file_url_protocol,
|
|
cwd = cwd_normalized
|
|
)
|
|
);
|
|
|
|
// STDOUT should contain HTML from the local file
|
|
assert_eq!(
|
|
String::from_utf8_lossy(&out.stdout),
|
|
"\
|
|
<!DOCTYPE html><html lang=\"en\"><head>\n \
|
|
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n \
|
|
<title>Local HTML file</title>\n \
|
|
<link href=\"data:text/css;base64,Ym9keSB7CiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDAwOwogICAgY29sb3I6ICNmZmY7Cn0K\" rel=\"stylesheet\" type=\"text/css\">\n \
|
|
<link rel=\"stylesheet\" type=\"text/css\">\n</head>\n\n<body>\n \
|
|
<img alt=\"\">\n \
|
|
<a href=\"file://local-file.html/\">Tricky href</a>\n \
|
|
<a href=\"https://github.com/Y2Z/monolith\">Remote URL</a>\n \
|
|
<script src=\"data:application/javascript;base64,ZG9jdW1lbnQuYm9keS5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSAiZ3JlZW4iOwpkb2N1bWVudC5ib2R5LnN0eWxlLmNvbG9yID0gInJlZCI7Cg==\"></script>\n\n\n\n\
|
|
</body></html>\n\
|
|
"
|
|
);
|
|
|
|
// Exit code should be 0
|
|
out.assert().code(0);
|
|
}
|
|
|
|
#[test]
|
|
fn local_file_target_input_absolute_target_path() {
|
|
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap();
|
|
let path_html: &Path = Path::new("tests/_data_/basic/local-file.html");
|
|
|
|
let out = cmd
|
|
.arg("-M")
|
|
.arg("-Ijci")
|
|
.arg(path_html.as_os_str())
|
|
.output()
|
|
.unwrap();
|
|
|
|
// STDERR should contain only the target file
|
|
assert_eq!(
|
|
String::from_utf8_lossy(&out.stderr),
|
|
format!(
|
|
"{file_url_html}\n",
|
|
file_url_html = Url::from_file_path(fs::canonicalize(&path_html).unwrap()).unwrap(),
|
|
)
|
|
);
|
|
|
|
// STDOUT should contain HTML from the local file
|
|
assert_eq!(
|
|
String::from_utf8_lossy(&out.stdout),
|
|
format!(
|
|
"\
|
|
<!DOCTYPE html><html lang=\"en\"><head>\
|
|
<meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'unsafe-eval' 'unsafe-inline' data:; style-src 'none'; script-src 'none'; img-src data:;\"></meta>\n \
|
|
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n \
|
|
<title>Local HTML file</title>\n \
|
|
<link rel=\"stylesheet\" type=\"text/css\">\n \
|
|
<link rel=\"stylesheet\" type=\"text/css\">\n</head>\n\n<body>\n \
|
|
<img src=\"{empty_image}\" alt=\"\">\n \
|
|
<a href=\"file://local-file.html/\">Tricky href</a>\n \
|
|
<a href=\"https://github.com/Y2Z/monolith\">Remote URL</a>\n \
|
|
<script></script>\n\n\n\n\
|
|
</body></html>\n\
|
|
",
|
|
empty_image = EMPTY_IMAGE_DATA_URL
|
|
)
|
|
);
|
|
|
|
// Exit code should be 0
|
|
out.assert().code(0);
|
|
}
|
|
|
|
#[test]
|
|
fn local_file_url_target_input() {
|
|
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap();
|
|
let cwd_normalized: String = env::current_dir()
|
|
.unwrap()
|
|
.to_str()
|
|
.unwrap()
|
|
.replace("\\", "/");
|
|
let file_url_protocol: &str = if cfg!(windows) { "file:///" } else { "file://" };
|
|
let out = cmd
|
|
.arg("-M")
|
|
.arg("-cji")
|
|
.arg(format!(
|
|
"{file}{cwd}/tests/_data_/basic/local-file.html",
|
|
file = file_url_protocol,
|
|
cwd = cwd_normalized,
|
|
))
|
|
.output()
|
|
.unwrap();
|
|
|
|
// STDERR should contain list of retrieved file URLs
|
|
assert_eq!(
|
|
String::from_utf8_lossy(&out.stderr),
|
|
format!(
|
|
"{file}{cwd}/tests/_data_/basic/local-file.html\n",
|
|
file = file_url_protocol,
|
|
cwd = cwd_normalized,
|
|
)
|
|
);
|
|
|
|
// STDOUT should contain HTML from the local file
|
|
assert_eq!(
|
|
String::from_utf8_lossy(&out.stdout),
|
|
format!(
|
|
"\
|
|
<!DOCTYPE html><html lang=\"en\"><head>\
|
|
<meta http-equiv=\"Content-Security-Policy\" content=\"style-src 'none'; script-src 'none'; img-src data:;\"></meta>\n \
|
|
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n \
|
|
<title>Local HTML file</title>\n \
|
|
<link rel=\"stylesheet\" type=\"text/css\">\n \
|
|
<link rel=\"stylesheet\" type=\"text/css\">\n</head>\n\n<body>\n \
|
|
<img src=\"{empty_image}\" alt=\"\">\n \
|
|
<a href=\"file://local-file.html/\">Tricky href</a>\n \
|
|
<a href=\"https://github.com/Y2Z/monolith\">Remote URL</a>\n \
|
|
<script></script>\n\n\n\n\
|
|
</body></html>\n\
|
|
",
|
|
empty_image = EMPTY_IMAGE_DATA_URL
|
|
)
|
|
);
|
|
|
|
// Exit code should be 0
|
|
out.assert().code(0);
|
|
}
|
|
|
|
#[test]
|
|
fn embed_file_url_local_asset_within_style_attribute() {
|
|
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap();
|
|
let path_html: &Path = Path::new("tests/_data_/svg/index.html");
|
|
let path_svg: &Path = Path::new("tests/_data_/svg/image.svg");
|
|
|
|
let out = cmd.arg("-M").arg(path_html.as_os_str()).output().unwrap();
|
|
|
|
// STDERR should list files that got retrieved
|
|
assert_eq!(
|
|
String::from_utf8_lossy(&out.stderr),
|
|
format!(
|
|
"\
|
|
{file_url_html}\n \
|
|
{file_url_svg}\n\
|
|
",
|
|
file_url_html = Url::from_file_path(fs::canonicalize(&path_html).unwrap()).unwrap(),
|
|
file_url_svg = Url::from_file_path(fs::canonicalize(&path_svg).unwrap()).unwrap(),
|
|
)
|
|
);
|
|
|
|
// STDOUT should contain HTML with date URL for background-image in it
|
|
assert_eq!(
|
|
String::from_utf8_lossy(&out.stdout),
|
|
"<html><head></head><body><div style=\"background-image: url("data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGJhc2VQcm9maWxlPSJmdWxsIiB3aWR0aD0iMzAwIiBoZWlnaHQ9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InJlZCIgLz4KICAgIDxjaXJjbGUgY3g9IjE1MCIgY3k9IjEwMCIgcj0iODAiIGZpbGw9ImdyZWVuIiAvPgogICAgPHRleHQgeD0iMTUwIiB5PSIxMjUiIGZvbnQtc2l6ZT0iNjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZpbGw9IndoaXRlIj5TVkc8L3RleHQ+Cjwvc3ZnPgo=")\"></div>\n</body></html>\n"
|
|
);
|
|
|
|
// Exit code should be 0
|
|
out.assert().code(0);
|
|
}
|
|
|
|
#[test]
|
|
fn discard_integrity_for_local_files() {
|
|
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap();
|
|
let cwd_normalized: String = env::current_dir()
|
|
.unwrap()
|
|
.to_str()
|
|
.unwrap()
|
|
.replace("\\", "/");
|
|
let file_url_protocol: &str = if cfg!(windows) { "file:///" } else { "file://" };
|
|
let out = cmd
|
|
.arg("-M")
|
|
.arg("-i")
|
|
.arg(if cfg!(windows) {
|
|
format!(
|
|
"{file}{cwd}/tests/_data_/integrity/index.html",
|
|
file = file_url_protocol,
|
|
cwd = cwd_normalized,
|
|
)
|
|
} else {
|
|
format!(
|
|
"{file}{cwd}/tests/_data_/integrity/index.html",
|
|
file = file_url_protocol,
|
|
cwd = cwd_normalized,
|
|
)
|
|
})
|
|
.output()
|
|
.unwrap();
|
|
|
|
// STDERR should contain list of retrieved file URLs
|
|
assert_eq!(
|
|
String::from_utf8_lossy(&out.stderr),
|
|
format!(
|
|
"\
|
|
{file}{cwd}/tests/_data_/integrity/index.html\n \
|
|
{file}{cwd}/tests/_data_/integrity/style.css\n \
|
|
{file}{cwd}/tests/_data_/integrity/style.css\n \
|
|
{file}{cwd}/tests/_data_/integrity/script.js\n \
|
|
{file}{cwd}/tests/_data_/integrity/script.js\n\
|
|
",
|
|
file = file_url_protocol,
|
|
cwd = cwd_normalized,
|
|
)
|
|
);
|
|
|
|
// STDOUT should contain HTML from the local file; integrity attributes should be missing
|
|
assert_eq!(
|
|
String::from_utf8_lossy(&out.stdout),
|
|
format!(
|
|
"\
|
|
<!DOCTYPE html><html lang=\"en\"><head>\
|
|
<meta http-equiv=\"Content-Security-Policy\" content=\"img-src data:;\"></meta>\n \
|
|
<title>Local HTML file</title>\n \
|
|
<link href=\"data:text/css;base64,Ym9keSB7CiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDAwOwogICAgY29sb3I6ICNGRkY7Cn0K\" rel=\"stylesheet\" type=\"text/css\" crossorigin=\"anonymous\">\n \
|
|
<link href=\"style.css\" rel=\"stylesheet\" type=\"text/css\" crossorigin=\"anonymous\">\n</head>\n\n<body>\n \
|
|
<p>This page should have black background and white foreground, but only when served via http: (not via file:)</p>\n \
|
|
<script src=\"data:application/javascript;base64,ZnVuY3Rpb24gbm9vcCgpIHsKICAgIGNvbnNvbGUubG9nKCJtb25vbGl0aCIpOwp9Cg==\"></script>\n \
|
|
<script src=\"script.js\"></script>\n\n\n\n\
|
|
</body></html>\n\
|
|
"
|
|
)
|
|
);
|
|
|
|
// Exit code should be 0
|
|
out.assert().code(0);
|
|
}
|
|
}
|