group all tests into either passing or failing groups
This commit is contained in:
parent
3d678d80ee
commit
090d647390
20 changed files with 2256 additions and 2143 deletions
900
src/tests/cli.rs
900
src/tests/cli.rs
|
@ -1,9 +1,3 @@
|
||||||
use assert_cmd::prelude::*;
|
|
||||||
use std::env;
|
|
||||||
use std::io::Write;
|
|
||||||
use std::process::Command;
|
|
||||||
use tempfile::NamedTempFile;
|
|
||||||
|
|
||||||
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
||||||
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
||||||
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
||||||
|
@ -11,519 +5,527 @@ use tempfile::NamedTempFile;
|
||||||
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn passing_print_version() -> Result<(), Box<dyn std::error::Error>> {
|
mod passing {
|
||||||
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
use assert_cmd::prelude::*;
|
||||||
let out = cmd.arg("-V").output().unwrap();
|
use std::env;
|
||||||
|
use std::io::Write;
|
||||||
|
use std::process::Command;
|
||||||
|
use tempfile::NamedTempFile;
|
||||||
|
|
||||||
// STDOUT should contain program name and version
|
#[test]
|
||||||
assert_eq!(
|
fn print_version() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
std::str::from_utf8(&out.stdout).unwrap(),
|
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
||||||
format!("{} {}\n", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"))
|
let out = cmd.arg("-V").output().unwrap();
|
||||||
);
|
|
||||||
|
|
||||||
// STDERR should be empty
|
// STDOUT should contain program name and version
|
||||||
assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), "");
|
assert_eq!(
|
||||||
|
std::str::from_utf8(&out.stdout).unwrap(),
|
||||||
|
format!("{} {}\n", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"))
|
||||||
|
);
|
||||||
|
|
||||||
// The exit code should be 0
|
// STDERR should be empty
|
||||||
out.assert().code(0);
|
assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), "");
|
||||||
|
|
||||||
Ok(())
|
// The exit code should be 0
|
||||||
}
|
out.assert().code(0);
|
||||||
|
|
||||||
#[test]
|
Ok(())
|
||||||
fn passing_bad_input_empty_target() -> Result<(), Box<dyn std::error::Error>> {
|
}
|
||||||
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
|
||||||
let out = cmd.arg("").output().unwrap();
|
|
||||||
|
|
||||||
// STDOUT should be empty
|
#[test]
|
||||||
assert_eq!(std::str::from_utf8(&out.stdout).unwrap(), "");
|
fn bad_input_empty_target() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
||||||
|
let out = cmd.arg("").output().unwrap();
|
||||||
|
|
||||||
// STDERR should contain error description
|
// STDOUT should be empty
|
||||||
assert_eq!(
|
assert_eq!(std::str::from_utf8(&out.stdout).unwrap(), "");
|
||||||
std::str::from_utf8(&out.stderr).unwrap(),
|
|
||||||
"No target specified\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
// The exit code should be 1
|
// STDERR should contain error description
|
||||||
out.assert().code(1);
|
assert_eq!(
|
||||||
|
std::str::from_utf8(&out.stderr).unwrap(),
|
||||||
|
"No target specified\n"
|
||||||
|
);
|
||||||
|
|
||||||
Ok(())
|
// The exit code should be 1
|
||||||
}
|
out.assert().code(1);
|
||||||
|
|
||||||
#[test]
|
Ok(())
|
||||||
fn passing_bad_input_data_url() -> Result<(), Box<dyn std::error::Error>> {
|
}
|
||||||
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
|
||||||
let out = cmd.arg("data:,Hello%2C%20World!").output().unwrap();
|
|
||||||
|
|
||||||
// STDOUT should contain HTML
|
#[test]
|
||||||
assert_eq!(std::str::from_utf8(&out.stdout).unwrap(), "");
|
fn bad_input_data_url() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
||||||
|
let out = cmd.arg("data:,Hello%2C%20World!").output().unwrap();
|
||||||
|
|
||||||
// STDERR should contain error description
|
// STDOUT should contain HTML
|
||||||
assert_eq!(
|
assert_eq!(std::str::from_utf8(&out.stdout).unwrap(), "");
|
||||||
std::str::from_utf8(&out.stderr).unwrap(),
|
|
||||||
"Unsupported data URL media type\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
// The exit code should be 1
|
// STDERR should contain error description
|
||||||
out.assert().code(1);
|
assert_eq!(
|
||||||
|
std::str::from_utf8(&out.stderr).unwrap(),
|
||||||
|
"Unsupported data URL media type\n"
|
||||||
|
);
|
||||||
|
|
||||||
Ok(())
|
// The exit code should be 1
|
||||||
}
|
out.assert().code(1);
|
||||||
|
|
||||||
#[test]
|
Ok(())
|
||||||
fn passing_isolate_data_url() -> Result<(), Box<dyn std::error::Error>> {
|
}
|
||||||
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
|
||||||
let out = cmd
|
|
||||||
.arg("-M")
|
|
||||||
.arg("-I")
|
|
||||||
.arg("data:text/html,Hello%2C%20World!")
|
|
||||||
.output()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// STDOUT should contain isolated HTML
|
#[test]
|
||||||
assert_eq!(
|
fn isolate_data_url() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
std::str::from_utf8(&out.stdout).unwrap(),
|
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
||||||
"<html><head>\
|
let out = cmd
|
||||||
<meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'unsafe-inline' data:;\"></meta>\
|
.arg("-M")
|
||||||
</head><body>Hello, World!</body></html>\n"
|
.arg("-I")
|
||||||
);
|
.arg("data:text/html,Hello%2C%20World!")
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// STDERR should be empty
|
// STDOUT should contain isolated HTML
|
||||||
assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), "");
|
assert_eq!(
|
||||||
|
std::str::from_utf8(&out.stdout).unwrap(),
|
||||||
|
"<html><head>\
|
||||||
|
<meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'unsafe-inline' data:;\"></meta>\
|
||||||
|
</head><body>Hello, World!</body></html>\n"
|
||||||
|
);
|
||||||
|
|
||||||
// The exit code should be 0
|
// STDERR should be empty
|
||||||
out.assert().code(0);
|
assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), "");
|
||||||
|
|
||||||
Ok(())
|
// The exit code should be 0
|
||||||
}
|
out.assert().code(0);
|
||||||
|
|
||||||
#[test]
|
Ok(())
|
||||||
fn passing_remove_css_from_data_url() -> Result<(), Box<dyn std::error::Error>> {
|
}
|
||||||
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
|
||||||
let out = cmd
|
|
||||||
.arg("-M")
|
|
||||||
.arg("-c")
|
|
||||||
.arg("data:text/html,<style>body{background-color:pink}</style>Hello")
|
|
||||||
.output()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// STDOUT should contain HTML with no CSS
|
#[test]
|
||||||
assert_eq!(
|
fn remove_css_from_data_url() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
std::str::from_utf8(&out.stdout).unwrap(),
|
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
||||||
"<html><head>\
|
let out = cmd
|
||||||
<meta http-equiv=\"Content-Security-Policy\" content=\"style-src 'none';\"></meta>\
|
.arg("-M")
|
||||||
<style></style>\
|
.arg("-c")
|
||||||
</head><body>Hello</body></html>\n"
|
.arg("data:text/html,<style>body{background-color:pink}</style>Hello")
|
||||||
);
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// STDERR should be empty
|
// STDOUT should contain HTML with no CSS
|
||||||
assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), "");
|
assert_eq!(
|
||||||
|
std::str::from_utf8(&out.stdout).unwrap(),
|
||||||
|
"<html><head>\
|
||||||
|
<meta http-equiv=\"Content-Security-Policy\" content=\"style-src 'none';\"></meta>\
|
||||||
|
<style></style>\
|
||||||
|
</head><body>Hello</body></html>\n"
|
||||||
|
);
|
||||||
|
|
||||||
// The exit code should be 0
|
// STDERR should be empty
|
||||||
out.assert().code(0);
|
assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), "");
|
||||||
|
|
||||||
Ok(())
|
// The exit code should be 0
|
||||||
}
|
out.assert().code(0);
|
||||||
|
|
||||||
#[test]
|
Ok(())
|
||||||
fn passing_remove_frames_from_data_url() -> Result<(), Box<dyn std::error::Error>> {
|
}
|
||||||
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
|
||||||
let out = cmd
|
|
||||||
.arg("-M")
|
|
||||||
.arg("-f")
|
|
||||||
.arg("data:text/html,<iframe src=\"https://google.com\"></iframe>Hi")
|
|
||||||
.output()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// STDOUT should contain HTML with no iframes
|
#[test]
|
||||||
assert_eq!(
|
fn remove_frames_from_data_url() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
std::str::from_utf8(&out.stdout).unwrap(),
|
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
||||||
"<html><head>\
|
let out = cmd
|
||||||
<meta http-equiv=\"Content-Security-Policy\" content=\"frame-src 'none';child-src 'none';\"></meta>\
|
.arg("-M")
|
||||||
</head><body><iframe src=\"\"></iframe>Hi</body></html>\n"
|
.arg("-f")
|
||||||
);
|
.arg("data:text/html,<iframe src=\"https://google.com\"></iframe>Hi")
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// STDERR should be empty
|
// STDOUT should contain HTML with no iframes
|
||||||
assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), "");
|
assert_eq!(
|
||||||
|
std::str::from_utf8(&out.stdout).unwrap(),
|
||||||
|
"<html><head>\
|
||||||
|
<meta http-equiv=\"Content-Security-Policy\" content=\"frame-src 'none';child-src 'none';\"></meta>\
|
||||||
|
</head><body><iframe src=\"\"></iframe>Hi</body></html>\n"
|
||||||
|
);
|
||||||
|
|
||||||
// The exit code should be 0
|
// STDERR should be empty
|
||||||
out.assert().code(0);
|
assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), "");
|
||||||
|
|
||||||
Ok(())
|
// The exit code should be 0
|
||||||
}
|
out.assert().code(0);
|
||||||
|
|
||||||
#[test]
|
Ok(())
|
||||||
fn passing_remove_images_from_data_url() -> Result<(), Box<dyn std::error::Error>> {
|
}
|
||||||
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
|
||||||
let out = cmd
|
|
||||||
.arg("-M")
|
|
||||||
.arg("-i")
|
|
||||||
.arg("data:text/html,<img src=\"https://google.com\"/>Hi")
|
|
||||||
.output()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// STDOUT should contain HTML with no images
|
#[test]
|
||||||
assert_eq!(
|
fn remove_images_from_data_url() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
std::str::from_utf8(&out.stdout).unwrap(),
|
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
||||||
format!(
|
let out = cmd
|
||||||
|
.arg("-M")
|
||||||
|
.arg("-i")
|
||||||
|
.arg("data:text/html,<img src=\"https://google.com\"/>Hi")
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// STDOUT should contain HTML with no images
|
||||||
|
assert_eq!(
|
||||||
|
std::str::from_utf8(&out.stdout).unwrap(),
|
||||||
|
format!(
|
||||||
|
"<html>\
|
||||||
|
<head>\
|
||||||
|
<meta http-equiv=\"Content-Security-Policy\" content=\"img-src data:;\"></meta>\
|
||||||
|
</head>\
|
||||||
|
<body>\
|
||||||
|
<img src=\"{empty_image}\">\
|
||||||
|
Hi\
|
||||||
|
</body>\
|
||||||
|
</html>\n",
|
||||||
|
empty_image = empty_image!()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 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 remove_js_from_data_url() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
||||||
|
let out = cmd
|
||||||
|
.arg("-M")
|
||||||
|
.arg("-j")
|
||||||
|
.arg("data:text/html,<script>alert(2)</script>Hi")
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// STDOUT should contain HTML with no JS
|
||||||
|
assert_eq!(
|
||||||
|
std::str::from_utf8(&out.stdout).unwrap(),
|
||||||
"<html>\
|
"<html>\
|
||||||
<head>\
|
<head>\
|
||||||
<meta http-equiv=\"Content-Security-Policy\" content=\"img-src data:;\"></meta>\
|
<meta http-equiv=\"Content-Security-Policy\" content=\"script-src 'none';\"></meta>\
|
||||||
</head>\
|
<script></script></head>\
|
||||||
<body>\
|
<body>Hi</body>\
|
||||||
<img src=\"{empty_image}\">\
|
</html>\n"
|
||||||
Hi\
|
);
|
||||||
</body>\
|
|
||||||
</html>\n",
|
|
||||||
empty_image = empty_image!()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
// STDERR should be empty
|
// STDERR should be empty
|
||||||
assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), "");
|
assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), "");
|
||||||
|
|
||||||
// The exit code should be 0
|
// The exit code should be 0
|
||||||
out.assert().code(0);
|
out.assert().code(0);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_remove_js_from_data_url() -> Result<(), Box<dyn std::error::Error>> {
|
fn local_file_target_input() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
||||||
let out = cmd
|
let cwd_normalized: String =
|
||||||
.arg("-M")
|
str!(env::current_dir().unwrap().to_str().unwrap()).replace("\\", "/");
|
||||||
.arg("-j")
|
let out = cmd
|
||||||
.arg("data:text/html,<script>alert(2)</script>Hi")
|
.arg("-M")
|
||||||
.output()
|
.arg(if cfg!(windows) {
|
||||||
.unwrap();
|
"src\\tests\\data\\basic\\local-file.html"
|
||||||
|
} else {
|
||||||
|
"src/tests/data/basic/local-file.html"
|
||||||
|
})
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
let file_url_protocol: &str = if cfg!(windows) { "file:///" } else { "file://" };
|
||||||
|
|
||||||
// STDOUT should contain HTML with no JS
|
// STDOUT should contain HTML from the local file
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
std::str::from_utf8(&out.stdout).unwrap(),
|
std::str::from_utf8(&out.stdout).unwrap(),
|
||||||
"<html>\
|
|
||||||
<head>\
|
|
||||||
<meta http-equiv=\"Content-Security-Policy\" content=\"script-src 'none';\"></meta>\
|
|
||||||
<script></script></head>\
|
|
||||||
<body>Hi</body>\
|
|
||||||
</html>\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<dyn std::error::Error>> {
|
|
||||||
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("-M")
|
|
||||||
.arg(if cfg!(windows) {
|
|
||||||
"src\\tests\\data\\basic\\local-file.html"
|
|
||||||
} else {
|
|
||||||
"src/tests/data/basic/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(),
|
|
||||||
"\
|
|
||||||
<!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 rel=\"stylesheet\" type=\"text/css\" href=\"data:text/css;base64,Ym9keSB7CiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDAwOwogICAgY29sb3I6ICNmZmY7Cn0K\">\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\
|
|
||||||
"
|
|
||||||
);
|
|
||||||
|
|
||||||
// STDERR should contain list of retrieved file URLs
|
|
||||||
assert_eq!(
|
|
||||||
std::str::from_utf8(&out.stderr).unwrap(),
|
|
||||||
format!(
|
|
||||||
"\
|
"\
|
||||||
{file}{cwd}/src/tests/data/basic/local-file.html\n\
|
<!DOCTYPE html><html lang=\"en\"><head>\n \
|
||||||
{file}{cwd}/src/tests/data/basic/local-style.css\n\
|
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n \
|
||||||
{file}{cwd}/src/tests/data/basic/local-script.js\n\
|
<title>Local HTML file</title>\n \
|
||||||
",
|
<link rel=\"stylesheet\" type=\"text/css\" href=\"data:text/css;base64,Ym9keSB7CiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDAwOwogICAgY29sb3I6ICNmZmY7Cn0K\">\n \
|
||||||
file = file_url_protocol,
|
<link rel=\"stylesheet\" type=\"text/css\">\n</head>\n\n<body>\n \
|
||||||
cwd = cwd_normalized
|
<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\
|
||||||
|
"
|
||||||
|
);
|
||||||
|
|
||||||
// The exit code should be 0
|
// STDERR should contain list of retrieved file URLs
|
||||||
out.assert().code(0);
|
assert_eq!(
|
||||||
|
std::str::from_utf8(&out.stderr).unwrap(),
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn passing_local_file_target_input_absolute_target_path() -> Result<(), Box<dyn std::error::Error>>
|
|
||||||
{
|
|
||||||
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("-M")
|
|
||||||
.arg("-jciI")
|
|
||||||
.arg(if cfg!(windows) {
|
|
||||||
format!(
|
format!(
|
||||||
"{cwd}\\src\\tests\\data\\basic\\local-file.html",
|
"\
|
||||||
cwd = cwd.to_str().unwrap()
|
{file}{cwd}/src/tests/data/basic/local-file.html\n\
|
||||||
)
|
{file}{cwd}/src/tests/data/basic/local-style.css\n\
|
||||||
} else {
|
{file}{cwd}/src/tests/data/basic/local-script.js\n\
|
||||||
format!(
|
",
|
||||||
"{cwd}/src/tests/data/basic/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(),
|
|
||||||
format!(
|
|
||||||
"\
|
|
||||||
<!DOCTYPE html><html lang=\"en\"><head>\
|
|
||||||
<meta http-equiv=\"Content-Security-Policy\" content=\"default-src '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 alt=\"\" src=\"{empty_image}\">\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!()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
// STDERR should contain only the target file
|
|
||||||
assert_eq!(
|
|
||||||
std::str::from_utf8(&out.stderr).unwrap(),
|
|
||||||
format!(
|
|
||||||
"{file}{cwd}/src/tests/data/basic/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<dyn std::error::Error>> {
|
|
||||||
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
|
||||||
let cwd_normalized: String =
|
|
||||||
str!(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(if cfg!(windows) {
|
|
||||||
format!(
|
|
||||||
"{file}{cwd}/src/tests/data/basic/local-file.html",
|
|
||||||
file = file_url_protocol,
|
file = file_url_protocol,
|
||||||
cwd = cwd_normalized,
|
cwd = cwd_normalized
|
||||||
)
|
)
|
||||||
} else {
|
);
|
||||||
|
|
||||||
|
// The exit code should be 0
|
||||||
|
out.assert().code(0);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn local_file_target_input_absolute_target_path() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
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("-M")
|
||||||
|
.arg("-jciI")
|
||||||
|
.arg(if cfg!(windows) {
|
||||||
|
format!(
|
||||||
|
"{cwd}\\src\\tests\\data\\basic\\local-file.html",
|
||||||
|
cwd = cwd.to_str().unwrap()
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
format!(
|
||||||
|
"{cwd}/src/tests/data/basic/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(),
|
||||||
format!(
|
format!(
|
||||||
"{file}{cwd}/src/tests/data/basic/local-file.html",
|
"\
|
||||||
file = file_url_protocol,
|
<!DOCTYPE html><html lang=\"en\"><head>\
|
||||||
cwd = cwd_normalized,
|
<meta http-equiv=\"Content-Security-Policy\" content=\"default-src '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 alt=\"\" src=\"{empty_image}\">\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!()
|
||||||
)
|
)
|
||||||
})
|
);
|
||||||
.output()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// STDOUT should contain HTML from the local file
|
// STDERR should contain only the target file
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
std::str::from_utf8(&out.stdout).unwrap(),
|
std::str::from_utf8(&out.stderr).unwrap(),
|
||||||
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 alt=\"\" src=\"{empty_image}\">\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!()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
// STDERR should contain list of retrieved file URLs
|
|
||||||
assert_eq!(
|
|
||||||
std::str::from_utf8(&out.stderr).unwrap(),
|
|
||||||
if cfg!(windows) {
|
|
||||||
format!(
|
format!(
|
||||||
"{file}{cwd}/src/tests/data/basic/local-file.html\n",
|
"{file}{cwd}/src/tests/data/basic/local-file.html\n",
|
||||||
file = file_url_protocol,
|
file = file_url_protocol,
|
||||||
cwd = cwd_normalized,
|
cwd = cwd_normalized,
|
||||||
)
|
)
|
||||||
} else {
|
);
|
||||||
|
|
||||||
|
// The exit code should be 0
|
||||||
|
out.assert().code(0);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn local_file_url_target_input() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
||||||
|
let cwd_normalized: String =
|
||||||
|
str!(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(if cfg!(windows) {
|
||||||
|
format!(
|
||||||
|
"{file}{cwd}/src/tests/data/basic/local-file.html",
|
||||||
|
file = file_url_protocol,
|
||||||
|
cwd = cwd_normalized,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
format!(
|
||||||
|
"{file}{cwd}/src/tests/data/basic/local-file.html",
|
||||||
|
file = file_url_protocol,
|
||||||
|
cwd = cwd_normalized,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// STDOUT should contain HTML from the local file
|
||||||
|
assert_eq!(
|
||||||
|
std::str::from_utf8(&out.stdout).unwrap(),
|
||||||
format!(
|
format!(
|
||||||
"{file}{cwd}/src/tests/data/basic/local-file.html\n",
|
"\
|
||||||
file = file_url_protocol,
|
<!DOCTYPE html><html lang=\"en\"><head>\
|
||||||
cwd = cwd_normalized,
|
<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 alt=\"\" src=\"{empty_image}\">\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!()
|
||||||
)
|
)
|
||||||
}
|
);
|
||||||
);
|
|
||||||
|
|
||||||
// The exit code should be 0
|
// STDERR should contain list of retrieved file URLs
|
||||||
out.assert().code(0);
|
assert_eq!(
|
||||||
|
std::str::from_utf8(&out.stderr).unwrap(),
|
||||||
|
if cfg!(windows) {
|
||||||
|
format!(
|
||||||
|
"{file}{cwd}/src/tests/data/basic/local-file.html\n",
|
||||||
|
file = file_url_protocol,
|
||||||
|
cwd = cwd_normalized,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
format!(
|
||||||
|
"{file}{cwd}/src/tests/data/basic/local-file.html\n",
|
||||||
|
file = file_url_protocol,
|
||||||
|
cwd = cwd_normalized,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
Ok(())
|
// The exit code should be 0
|
||||||
}
|
out.assert().code(0);
|
||||||
|
|
||||||
#[test]
|
Ok(())
|
||||||
fn passing_security_disallow_local_assets_within_data_url_targets(
|
}
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
|
||||||
let out = cmd
|
|
||||||
.arg("-M")
|
|
||||||
.arg("data:text/html,%3Cscript%20src=\"src/tests/data/basic/local-script.js\"%3E%3C/script%3E")
|
|
||||||
.output()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// STDOUT should contain HTML with no JS in it
|
#[test]
|
||||||
assert_eq!(
|
fn security_disallow_local_assets_within_data_url_targets(
|
||||||
std::str::from_utf8(&out.stdout).unwrap(),
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
"<html><head><script></script></head><body></body></html>\n"
|
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
||||||
);
|
let out = cmd
|
||||||
|
.arg("-M")
|
||||||
|
.arg("data:text/html,%3Cscript%20src=\"src/tests/data/basic/local-script.js\"%3E%3C/script%3E")
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// STDERR should be empty
|
// STDOUT should contain HTML with no JS in it
|
||||||
assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), "");
|
assert_eq!(
|
||||||
|
std::str::from_utf8(&out.stdout).unwrap(),
|
||||||
|
"<html><head><script></script></head><body></body></html>\n"
|
||||||
|
);
|
||||||
|
|
||||||
// The exit code should be 0
|
// STDERR should be empty
|
||||||
out.assert().code(0);
|
assert_eq!(std::str::from_utf8(&out.stderr).unwrap(), "");
|
||||||
|
|
||||||
Ok(())
|
// The exit code should be 0
|
||||||
}
|
out.assert().code(0);
|
||||||
|
|
||||||
#[test]
|
Ok(())
|
||||||
fn passing_embed_file_url_local_asset_within_style_attribute(
|
}
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
let file_url_prefix: &str = if cfg!(windows) { "file:///" } else { "file://" };
|
|
||||||
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
|
||||||
let mut file_svg = NamedTempFile::new()?;
|
|
||||||
writeln!(file_svg, "<svg version=\"1.1\" baseProfile=\"full\" width=\"300\" height=\"200\" xmlns=\"http://www.w3.org/2000/svg\">\
|
|
||||||
<rect width=\"100%\" height=\"100%\" fill=\"red\" />\
|
|
||||||
<circle cx=\"150\" cy=\"100\" r=\"80\" fill=\"green\" />\
|
|
||||||
<text x=\"150\" y=\"125\" font-size=\"60\" text-anchor=\"middle\" fill=\"white\">SVG</text>\
|
|
||||||
</svg>\n")?;
|
|
||||||
let mut file_html = NamedTempFile::new()?;
|
|
||||||
writeln!(
|
|
||||||
file_html,
|
|
||||||
"<div style='background-image: url(\"{file}{path}\")'></div>\n",
|
|
||||||
file = file_url_prefix,
|
|
||||||
path = str!(file_svg.path().to_str().unwrap()).replace("\\", "/"),
|
|
||||||
)?;
|
|
||||||
let out = cmd.arg("-M").arg(file_html.path()).output().unwrap();
|
|
||||||
|
|
||||||
// STDOUT should contain HTML with date URL for background-image in it
|
#[test]
|
||||||
assert_eq!(
|
fn embed_file_url_local_asset_within_style_attribute() -> Result<(), Box<dyn std::error::Error>>
|
||||||
std::str::from_utf8(&out.stdout).unwrap(),
|
{
|
||||||
"<html><head></head><body><div style=\"background-image: url('data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGJhc2VQcm9maWxlPSJmdWxsIiB3aWR0aD0iMzAwIiBoZWlnaHQ9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJyZWQiIC8+PGNpcmNsZSBjeD0iMTUwIiBjeT0iMTAwIiByPSI4MCIgZmlsbD0iZ3JlZW4iIC8+PHRleHQgeD0iMTUwIiB5PSIxMjUiIGZvbnQtc2l6ZT0iNjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZpbGw9IndoaXRlIj5TVkc8L3RleHQ+PC9zdmc+Cgo=')\"></div>\n\n</body></html>\n"
|
let file_url_prefix: &str = if cfg!(windows) { "file:///" } else { "file://" };
|
||||||
);
|
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
||||||
|
let mut file_svg = NamedTempFile::new()?;
|
||||||
// STDERR should list temporary files that got retrieved
|
writeln!(file_svg, "<svg version=\"1.1\" baseProfile=\"full\" width=\"300\" height=\"200\" xmlns=\"http://www.w3.org/2000/svg\">\
|
||||||
assert_eq!(
|
<rect width=\"100%\" height=\"100%\" fill=\"red\" />\
|
||||||
std::str::from_utf8(&out.stderr).unwrap(),
|
<circle cx=\"150\" cy=\"100\" r=\"80\" fill=\"green\" />\
|
||||||
format!(
|
<text x=\"150\" y=\"125\" font-size=\"60\" text-anchor=\"middle\" fill=\"white\">SVG</text>\
|
||||||
"\
|
</svg>\n")?;
|
||||||
{file}{html_path}\n\
|
let mut file_html = NamedTempFile::new()?;
|
||||||
{file}{svg_path}\n\
|
writeln!(
|
||||||
",
|
file_html,
|
||||||
|
"<div style='background-image: url(\"{file}{path}\")'></div>\n",
|
||||||
file = file_url_prefix,
|
file = file_url_prefix,
|
||||||
html_path = str!(file_html.path().to_str().unwrap()).replace("\\", "/"),
|
path = str!(file_svg.path().to_str().unwrap()).replace("\\", "/"),
|
||||||
svg_path = str!(file_svg.path().to_str().unwrap()).replace("\\", "/"),
|
)?;
|
||||||
)
|
let out = cmd.arg("-M").arg(file_html.path()).output().unwrap();
|
||||||
);
|
|
||||||
|
|
||||||
// The exit code should be 0
|
// STDOUT should contain HTML with date URL for background-image in it
|
||||||
out.assert().code(0);
|
assert_eq!(
|
||||||
|
std::str::from_utf8(&out.stdout).unwrap(),
|
||||||
|
"<html><head></head><body><div style=\"background-image: url('data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGJhc2VQcm9maWxlPSJmdWxsIiB3aWR0aD0iMzAwIiBoZWlnaHQ9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJyZWQiIC8+PGNpcmNsZSBjeD0iMTUwIiBjeT0iMTAwIiByPSI4MCIgZmlsbD0iZ3JlZW4iIC8+PHRleHQgeD0iMTUwIiB5PSIxMjUiIGZvbnQtc2l6ZT0iNjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZpbGw9IndoaXRlIj5TVkc8L3RleHQ+PC9zdmc+Cgo=')\"></div>\n\n</body></html>\n"
|
||||||
|
);
|
||||||
|
|
||||||
Ok(())
|
// STDERR should list temporary files that got retrieved
|
||||||
}
|
assert_eq!(
|
||||||
|
std::str::from_utf8(&out.stderr).unwrap(),
|
||||||
|
format!(
|
||||||
|
"\
|
||||||
|
{file}{html_path}\n\
|
||||||
|
{file}{svg_path}\n\
|
||||||
|
",
|
||||||
|
file = file_url_prefix,
|
||||||
|
html_path = str!(file_html.path().to_str().unwrap()).replace("\\", "/"),
|
||||||
|
svg_path = str!(file_svg.path().to_str().unwrap()).replace("\\", "/"),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
#[test]
|
// The exit code should be 0
|
||||||
fn passing_css_import_string() -> Result<(), Box<dyn std::error::Error>> {
|
out.assert().code(0);
|
||||||
let file_url_prefix: &str = if cfg!(windows) { "file:///" } else { "file://" };
|
|
||||||
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
|
||||||
let mut file_css = NamedTempFile::new()?;
|
|
||||||
writeln!(file_css, "body{{background-color:#000;color:#fff}}")?;
|
|
||||||
let mut file_html = NamedTempFile::new()?;
|
|
||||||
writeln!(
|
|
||||||
file_html,
|
|
||||||
"\
|
|
||||||
<style>\n\
|
|
||||||
@charset 'UTF-8';\n\
|
|
||||||
\n\
|
|
||||||
@import '{file}{css_path}';\n\
|
|
||||||
\n\
|
|
||||||
@import url({file}{css_path});\n\
|
|
||||||
\n\
|
|
||||||
@import url('{file}{css_path}')\n\
|
|
||||||
</style>\n\
|
|
||||||
",
|
|
||||||
file = file_url_prefix,
|
|
||||||
css_path = str!(file_css.path().to_str().unwrap()).replace("\\", "/"),
|
|
||||||
)?;
|
|
||||||
let out = cmd.arg("-M").arg(file_html.path()).output().unwrap();
|
|
||||||
|
|
||||||
// STDOUT should contain embedded CSS url()'s
|
Ok(())
|
||||||
assert_eq!(
|
}
|
||||||
std::str::from_utf8(&out.stdout).unwrap(),
|
|
||||||
"<html><head><style>\n@charset 'UTF-8';\n\n@import 'data:text/css;base64,Ym9keXtiYWNrZ3JvdW5kLWNvbG9yOiMwMDA7Y29sb3I6I2ZmZn0K';\n\n@import url('data:text/css;base64,Ym9keXtiYWNrZ3JvdW5kLWNvbG9yOiMwMDA7Y29sb3I6I2ZmZn0K');\n\n@import url('data:text/css;base64,Ym9keXtiYWNrZ3JvdW5kLWNvbG9yOiMwMDA7Y29sb3I6I2ZmZn0K')\n</style>\n\n</head><body></body></html>\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
// STDERR should list temporary files that got retrieved
|
#[test]
|
||||||
assert_eq!(
|
fn css_import_string() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
std::str::from_utf8(&out.stderr).unwrap(),
|
let file_url_prefix: &str = if cfg!(windows) { "file:///" } else { "file://" };
|
||||||
format!(
|
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?;
|
||||||
|
let mut file_css = NamedTempFile::new()?;
|
||||||
|
writeln!(file_css, "body{{background-color:#000;color:#fff}}")?;
|
||||||
|
let mut file_html = NamedTempFile::new()?;
|
||||||
|
writeln!(
|
||||||
|
file_html,
|
||||||
"\
|
"\
|
||||||
{file}{html_path}\n\
|
<style>\n\
|
||||||
{file}{css_path}\n\
|
@charset 'UTF-8';\n\
|
||||||
{file}{css_path}\n\
|
\n\
|
||||||
{file}{css_path}\n\
|
@import '{file}{css_path}';\n\
|
||||||
",
|
\n\
|
||||||
|
@import url({file}{css_path});\n\
|
||||||
|
\n\
|
||||||
|
@import url('{file}{css_path}')\n\
|
||||||
|
</style>\n\
|
||||||
|
",
|
||||||
file = file_url_prefix,
|
file = file_url_prefix,
|
||||||
html_path = str!(file_html.path().to_str().unwrap()).replace("\\", "/"),
|
|
||||||
css_path = str!(file_css.path().to_str().unwrap()).replace("\\", "/"),
|
css_path = str!(file_css.path().to_str().unwrap()).replace("\\", "/"),
|
||||||
)
|
)?;
|
||||||
);
|
let out = cmd.arg("-M").arg(file_html.path()).output().unwrap();
|
||||||
|
|
||||||
// The exit code should be 0
|
// STDOUT should contain embedded CSS url()'s
|
||||||
out.assert().code(0);
|
assert_eq!(
|
||||||
|
std::str::from_utf8(&out.stdout).unwrap(),
|
||||||
|
"<html><head><style>\n@charset 'UTF-8';\n\n@import 'data:text/css;base64,Ym9keXtiYWNrZ3JvdW5kLWNvbG9yOiMwMDA7Y29sb3I6I2ZmZn0K';\n\n@import url('data:text/css;base64,Ym9keXtiYWNrZ3JvdW5kLWNvbG9yOiMwMDA7Y29sb3I6I2ZmZn0K');\n\n@import url('data:text/css;base64,Ym9keXtiYWNrZ3JvdW5kLWNvbG9yOiMwMDA7Y29sb3I6I2ZmZn0K')\n</style>\n\n</head><body></body></html>\n"
|
||||||
|
);
|
||||||
|
|
||||||
Ok(())
|
// STDERR should list temporary files that got retrieved
|
||||||
|
assert_eq!(
|
||||||
|
std::str::from_utf8(&out.stderr).unwrap(),
|
||||||
|
format!(
|
||||||
|
"\
|
||||||
|
{file}{html_path}\n\
|
||||||
|
{file}{css_path}\n\
|
||||||
|
{file}{css_path}\n\
|
||||||
|
{file}{css_path}\n\
|
||||||
|
",
|
||||||
|
file = file_url_prefix,
|
||||||
|
html_path = str!(file_html.path().to_str().unwrap()).replace("\\", "/"),
|
||||||
|
css_path = str!(file_css.path().to_str().unwrap()).replace("\\", "/"),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// The exit code should be 0
|
||||||
|
out.assert().code(0);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
use reqwest::blocking::Client;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use crate::css;
|
|
||||||
|
|
||||||
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
||||||
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
||||||
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
||||||
|
@ -10,308 +5,315 @@ use crate::css;
|
||||||
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn passing_empty_input() {
|
mod passing {
|
||||||
let cache = &mut HashMap::new();
|
use crate::css;
|
||||||
let client = Client::new();
|
use reqwest::blocking::Client;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
assert_eq!(
|
#[test]
|
||||||
css::embed_css(cache, &client, "", "", false, false, false,),
|
fn empty_input() {
|
||||||
""
|
let cache = &mut HashMap::new();
|
||||||
);
|
let client = Client::new();
|
||||||
}
|
|
||||||
|
assert_eq!(
|
||||||
#[test]
|
css::embed_css(cache, &client, "", "", false, false, false,),
|
||||||
fn passing_style_exclude_unquoted_images() {
|
""
|
||||||
let cache = &mut HashMap::new();
|
);
|
||||||
let client = Client::new();
|
}
|
||||||
|
|
||||||
const STYLE: &str = "/* border: none;*/\
|
#[test]
|
||||||
background-image: url(https://somewhere.com/bg.png); \
|
fn style_exclude_unquoted_images() {
|
||||||
list-style: url(/assets/images/bullet.svg);\
|
let cache = &mut HashMap::new();
|
||||||
width:99.998%; \
|
let client = Client::new();
|
||||||
margin-top: -20px; \
|
|
||||||
line-height: -1; \
|
const STYLE: &str = "/* border: none;*/\
|
||||||
height: calc(100vh - 10pt)";
|
background-image: url(https://somewhere.com/bg.png); \
|
||||||
|
list-style: url(/assets/images/bullet.svg);\
|
||||||
assert_eq!(
|
width:99.998%; \
|
||||||
css::embed_css(
|
margin-top: -20px; \
|
||||||
cache,
|
line-height: -1; \
|
||||||
&client,
|
height: calc(100vh - 10pt)";
|
||||||
"https://doesntmatter.local/",
|
|
||||||
&STYLE,
|
assert_eq!(
|
||||||
false,
|
css::embed_css(
|
||||||
true,
|
cache,
|
||||||
true,
|
&client,
|
||||||
),
|
"https://doesntmatter.local/",
|
||||||
format!(
|
&STYLE,
|
||||||
"/* border: none;*/\
|
false,
|
||||||
background-image: url('{empty_image}'); \
|
true,
|
||||||
list-style: url('{empty_image}');\
|
true,
|
||||||
width:99.998%; \
|
),
|
||||||
margin-top: -20px; \
|
format!(
|
||||||
line-height: -1; \
|
"/* border: none;*/\
|
||||||
height: calc(100vh - 10pt)",
|
background-image: url('{empty_image}'); \
|
||||||
empty_image = empty_image!()
|
list-style: url('{empty_image}');\
|
||||||
)
|
width:99.998%; \
|
||||||
);
|
margin-top: -20px; \
|
||||||
}
|
line-height: -1; \
|
||||||
|
height: calc(100vh - 10pt)",
|
||||||
#[test]
|
empty_image = empty_image!()
|
||||||
fn passing_style_exclude_single_quoted_images() {
|
)
|
||||||
let cache = &mut HashMap::new();
|
);
|
||||||
let client = Client::new();
|
}
|
||||||
|
|
||||||
const STYLE: &str = "/* border: none;*/\
|
#[test]
|
||||||
background-image: url('https://somewhere.com/bg.png'); \
|
fn style_exclude_single_quoted_images() {
|
||||||
list-style: url('/assets/images/bullet.svg');\
|
let cache = &mut HashMap::new();
|
||||||
width:99.998%; \
|
let client = Client::new();
|
||||||
margin-top: -20px; \
|
|
||||||
line-height: -1; \
|
const STYLE: &str = "/* border: none;*/\
|
||||||
height: calc(100vh - 10pt)";
|
background-image: url('https://somewhere.com/bg.png'); \
|
||||||
|
list-style: url('/assets/images/bullet.svg');\
|
||||||
assert_eq!(
|
width:99.998%; \
|
||||||
css::embed_css(cache, &client, "", &STYLE, false, true, true,),
|
margin-top: -20px; \
|
||||||
format!(
|
line-height: -1; \
|
||||||
"/* border: none;*/\
|
height: calc(100vh - 10pt)";
|
||||||
background-image: url('{empty_image}'); \
|
|
||||||
list-style: url('{empty_image}');\
|
assert_eq!(
|
||||||
width:99.998%; \
|
css::embed_css(cache, &client, "", &STYLE, false, true, true,),
|
||||||
margin-top: -20px; \
|
format!(
|
||||||
line-height: -1; \
|
"/* border: none;*/\
|
||||||
height: calc(100vh - 10pt)",
|
background-image: url('{empty_image}'); \
|
||||||
empty_image = empty_image!()
|
list-style: url('{empty_image}');\
|
||||||
)
|
width:99.998%; \
|
||||||
);
|
margin-top: -20px; \
|
||||||
}
|
line-height: -1; \
|
||||||
|
height: calc(100vh - 10pt)",
|
||||||
#[test]
|
empty_image = empty_image!()
|
||||||
fn passing_style_block() {
|
)
|
||||||
let cache = &mut HashMap::new();
|
);
|
||||||
let client = Client::new();
|
}
|
||||||
|
|
||||||
const CSS: &str = "\
|
#[test]
|
||||||
#id.class-name:not(:nth-child(3n+0)) {\n \
|
fn style_block() {
|
||||||
// border: none;\n \
|
let cache = &mut HashMap::new();
|
||||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=');\n\
|
let client = Client::new();
|
||||||
}\n\
|
|
||||||
\n\
|
const CSS: &str = "\
|
||||||
html > body {}";
|
#id.class-name:not(:nth-child(3n+0)) {\n \
|
||||||
|
// border: none;\n \
|
||||||
assert_eq!(
|
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=');\n\
|
||||||
css::embed_css(cache, &client, "file:///", &CSS, false, false, true,),
|
}\n\
|
||||||
CSS
|
\n\
|
||||||
);
|
html > body {}";
|
||||||
}
|
|
||||||
|
assert_eq!(
|
||||||
#[test]
|
css::embed_css(cache, &client, "file:///", &CSS, false, false, true,),
|
||||||
fn passing_attribute_selectors() {
|
CSS
|
||||||
let cache = &mut HashMap::new();
|
);
|
||||||
let client = Client::new();
|
}
|
||||||
|
|
||||||
const CSS: &str = "\
|
#[test]
|
||||||
[data-value] {
|
fn attribute_selectors() {
|
||||||
/* Attribute exists */
|
let cache = &mut HashMap::new();
|
||||||
}
|
let client = Client::new();
|
||||||
|
|
||||||
[data-value='foo'] {
|
const CSS: &str = "\
|
||||||
/* Attribute has this exact value */
|
[data-value] {
|
||||||
}
|
/* Attribute exists */
|
||||||
|
}
|
||||||
[data-value*='foo'] {
|
|
||||||
/* Attribute value contains this value somewhere in it */
|
[data-value='foo'] {
|
||||||
}
|
/* Attribute has this exact value */
|
||||||
|
}
|
||||||
[data-value~='foo'] {
|
|
||||||
/* Attribute has this value in a space-separated list somewhere */
|
[data-value*='foo'] {
|
||||||
}
|
/* Attribute value contains this value somewhere in it */
|
||||||
|
}
|
||||||
[data-value^='foo'] {
|
|
||||||
/* Attribute value starts with this */
|
[data-value~='foo'] {
|
||||||
}
|
/* Attribute has this value in a space-separated list somewhere */
|
||||||
|
}
|
||||||
[data-value|='foo'] {
|
|
||||||
/* Attribute value starts with this in a dash-separated list */
|
[data-value^='foo'] {
|
||||||
}
|
/* Attribute value starts with this */
|
||||||
|
}
|
||||||
[data-value$='foo'] {
|
|
||||||
/* Attribute value ends with this */
|
[data-value|='foo'] {
|
||||||
}
|
/* Attribute value starts with this in a dash-separated list */
|
||||||
";
|
}
|
||||||
|
|
||||||
assert_eq!(
|
[data-value$='foo'] {
|
||||||
css::embed_css(cache, &client, "", &CSS, false, false, false,),
|
/* Attribute value ends with this */
|
||||||
CSS
|
}
|
||||||
);
|
";
|
||||||
}
|
|
||||||
|
assert_eq!(
|
||||||
#[test]
|
css::embed_css(cache, &client, "", &CSS, false, false, false,),
|
||||||
fn passing_import_string() {
|
CSS
|
||||||
let cache = &mut HashMap::new();
|
);
|
||||||
let client = Client::new();
|
}
|
||||||
|
|
||||||
const CSS: &str = "\
|
#[test]
|
||||||
@charset 'UTF-8';\n\
|
fn import_string() {
|
||||||
\n\
|
let cache = &mut HashMap::new();
|
||||||
@import 'data:text/css,html{background-color:%23000}';\n\
|
let client = Client::new();
|
||||||
\n\
|
|
||||||
@import url('data:text/css,html{color:%23fff}')\n\
|
const CSS: &str = "\
|
||||||
";
|
@charset 'UTF-8';\n\
|
||||||
|
\n\
|
||||||
assert_eq!(
|
@import 'data:text/css,html{background-color:%23000}';\n\
|
||||||
css::embed_css(
|
\n\
|
||||||
cache,
|
@import url('data:text/css,html{color:%23fff}')\n\
|
||||||
&client,
|
";
|
||||||
"https://doesntmatter.local/",
|
|
||||||
&CSS,
|
assert_eq!(
|
||||||
false,
|
css::embed_css(
|
||||||
false,
|
cache,
|
||||||
true,
|
&client,
|
||||||
),
|
"https://doesntmatter.local/",
|
||||||
"\
|
&CSS,
|
||||||
@charset 'UTF-8';\n\
|
false,
|
||||||
\n\
|
false,
|
||||||
@import 'data:text/css;base64,aHRtbHtiYWNrZ3JvdW5kLWNvbG9yOiMwMDB9';\n\
|
true,
|
||||||
\n\
|
),
|
||||||
@import url('data:text/css;base64,aHRtbHtjb2xvcjojZmZmfQ==')\n\
|
"\
|
||||||
"
|
@charset 'UTF-8';\n\
|
||||||
);
|
\n\
|
||||||
}
|
@import 'data:text/css;base64,aHRtbHtiYWNrZ3JvdW5kLWNvbG9yOiMwMDB9';\n\
|
||||||
|
\n\
|
||||||
#[test]
|
@import url('data:text/css;base64,aHRtbHtjb2xvcjojZmZmfQ==')\n\
|
||||||
fn passing_hash_urls() {
|
"
|
||||||
let cache = &mut HashMap::new();
|
);
|
||||||
let client = Client::new();
|
}
|
||||||
|
|
||||||
const CSS: &str = "\
|
#[test]
|
||||||
body {\n \
|
fn hash_urls() {
|
||||||
behavior: url(#default#something);\n\
|
let cache = &mut HashMap::new();
|
||||||
}\n\
|
let client = Client::new();
|
||||||
\n\
|
|
||||||
.scissorHalf {\n \
|
const CSS: &str = "\
|
||||||
offset-path: url(#somePath);\n\
|
body {\n \
|
||||||
}\n\
|
behavior: url(#default#something);\n\
|
||||||
";
|
}\n\
|
||||||
|
\n\
|
||||||
assert_eq!(
|
.scissorHalf {\n \
|
||||||
css::embed_css(
|
offset-path: url(#somePath);\n\
|
||||||
cache,
|
}\n\
|
||||||
&client,
|
";
|
||||||
"https://doesntmatter.local/",
|
|
||||||
&CSS,
|
assert_eq!(
|
||||||
false,
|
css::embed_css(
|
||||||
false,
|
cache,
|
||||||
true,
|
&client,
|
||||||
),
|
"https://doesntmatter.local/",
|
||||||
CSS
|
&CSS,
|
||||||
);
|
false,
|
||||||
}
|
false,
|
||||||
|
true,
|
||||||
#[test]
|
),
|
||||||
fn passing_transform_percentages_and_degrees() {
|
CSS
|
||||||
let cache = &mut HashMap::new();
|
);
|
||||||
let client = Client::new();
|
}
|
||||||
|
|
||||||
const CSS: &str = "\
|
#[test]
|
||||||
div {\n \
|
fn transform_percentages_and_degrees() {
|
||||||
transform: translate(-50%, -50%) rotate(-45deg);\n\
|
let cache = &mut HashMap::new();
|
||||||
transform: translate(50%, 50%) rotate(45deg);\n\
|
let client = Client::new();
|
||||||
transform: translate(+50%, +50%) rotate(+45deg);\n\
|
|
||||||
}\n\
|
const CSS: &str = "\
|
||||||
";
|
div {\n \
|
||||||
|
transform: translate(-50%, -50%) rotate(-45deg);\n\
|
||||||
assert_eq!(
|
transform: translate(50%, 50%) rotate(45deg);\n\
|
||||||
css::embed_css(
|
transform: translate(+50%, +50%) rotate(+45deg);\n\
|
||||||
cache,
|
}\n\
|
||||||
&client,
|
";
|
||||||
"https://doesntmatter.local/",
|
|
||||||
&CSS,
|
assert_eq!(
|
||||||
false,
|
css::embed_css(
|
||||||
false,
|
cache,
|
||||||
true,
|
&client,
|
||||||
),
|
"https://doesntmatter.local/",
|
||||||
CSS
|
&CSS,
|
||||||
);
|
false,
|
||||||
}
|
false,
|
||||||
|
true,
|
||||||
#[test]
|
),
|
||||||
fn passing_unusual_indents() {
|
CSS
|
||||||
let cache = &mut HashMap::new();
|
);
|
||||||
let client = Client::new();
|
}
|
||||||
|
|
||||||
const CSS: &str = "\
|
#[test]
|
||||||
.is\\:good:hover {\n \
|
fn unusual_indents() {
|
||||||
color: green\n\
|
let cache = &mut HashMap::new();
|
||||||
}\n\
|
let client = Client::new();
|
||||||
\n\
|
|
||||||
#\\~\\!\\@\\$\\%\\^\\&\\*\\(\\)\\+\\=\\,\\.\\/\\\\\\'\\\"\\;\\:\\?\\>\\<\\[\\]\\{\\}\\|\\`\\# {\n \
|
const CSS: &str = "\
|
||||||
color: black\n\
|
.is\\:good:hover {\n \
|
||||||
}\n\
|
color: green\n\
|
||||||
";
|
}\n\
|
||||||
|
\n\
|
||||||
assert_eq!(
|
#\\~\\!\\@\\$\\%\\^\\&\\*\\(\\)\\+\\=\\,\\.\\/\\\\\\'\\\"\\;\\:\\?\\>\\<\\[\\]\\{\\}\\|\\`\\# {\n \
|
||||||
css::embed_css(
|
color: black\n\
|
||||||
cache,
|
}\n\
|
||||||
&client,
|
";
|
||||||
"https://doesntmatter.local/",
|
|
||||||
&CSS,
|
assert_eq!(
|
||||||
false,
|
css::embed_css(
|
||||||
false,
|
cache,
|
||||||
true,
|
&client,
|
||||||
),
|
"https://doesntmatter.local/",
|
||||||
CSS
|
&CSS,
|
||||||
);
|
false,
|
||||||
}
|
false,
|
||||||
|
true,
|
||||||
#[test]
|
),
|
||||||
fn passing_exclude_fonts() {
|
CSS
|
||||||
let cache = &mut HashMap::new();
|
);
|
||||||
let client = Client::new();
|
}
|
||||||
|
|
||||||
const CSS: &str = "\
|
#[test]
|
||||||
@font-face {\n \
|
fn exclude_fonts() {
|
||||||
font-family: 'My Font';\n \
|
let cache = &mut HashMap::new();
|
||||||
src: url(my_font.woff);\n\
|
let client = Client::new();
|
||||||
}\n\
|
|
||||||
\n\
|
const CSS: &str = "\
|
||||||
#identifier {\n \
|
@font-face {\n \
|
||||||
font-family: 'My Font' Arial\n\
|
font-family: 'My Font';\n \
|
||||||
}\n\
|
src: url(my_font.woff);\n\
|
||||||
\n\
|
}\n\
|
||||||
@font-face {\n \
|
\n\
|
||||||
font-family: 'My Font';\n \
|
#identifier {\n \
|
||||||
src: url(my_font.woff);\n\
|
font-family: 'My Font' Arial\n\
|
||||||
}\n\
|
}\n\
|
||||||
\n\
|
\n\
|
||||||
div {\n \
|
@font-face {\n \
|
||||||
font-family: 'My Font' Verdana\n\
|
font-family: 'My Font';\n \
|
||||||
}\n\
|
src: url(my_font.woff);\n\
|
||||||
";
|
}\n\
|
||||||
|
\n\
|
||||||
const CSS_OUT: &str = " \
|
div {\n \
|
||||||
\n\
|
font-family: 'My Font' Verdana\n\
|
||||||
\n\
|
}\n\
|
||||||
#identifier {\n \
|
";
|
||||||
font-family: 'My Font' Arial\n\
|
|
||||||
}\n\
|
const CSS_OUT: &str = " \
|
||||||
\n \
|
\n\
|
||||||
\n\
|
\n\
|
||||||
\n\
|
#identifier {\n \
|
||||||
div {\n \
|
font-family: 'My Font' Arial\n\
|
||||||
font-family: 'My Font' Verdana\n\
|
}\n\
|
||||||
}\n\
|
\n \
|
||||||
";
|
\n\
|
||||||
|
\n\
|
||||||
assert_eq!(
|
div {\n \
|
||||||
css::embed_css(
|
font-family: 'My Font' Verdana\n\
|
||||||
cache,
|
}\n\
|
||||||
&client,
|
";
|
||||||
"https://doesntmatter.local/",
|
|
||||||
&CSS,
|
assert_eq!(
|
||||||
true,
|
css::embed_css(
|
||||||
false,
|
cache,
|
||||||
true,
|
&client,
|
||||||
),
|
"https://doesntmatter.local/",
|
||||||
CSS_OUT
|
&CSS,
|
||||||
);
|
true,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
),
|
||||||
|
CSS_OUT
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use crate::css;
|
|
||||||
|
|
||||||
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
||||||
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
||||||
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
||||||
|
@ -7,44 +5,49 @@ use crate::css;
|
||||||
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn passing_empty_input_single_quotes() {
|
mod passing {
|
||||||
assert_eq!(css::enquote(str!(""), false), "''");
|
use crate::css;
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_empty_input_double_quotes() {
|
fn empty_input_single_quotes() {
|
||||||
assert_eq!(css::enquote(str!(""), true), "\"\"");
|
assert_eq!(css::enquote(str!(""), false), "''");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_apostrophes_single_quotes() {
|
fn empty_input_double_quotes() {
|
||||||
assert_eq!(
|
assert_eq!(css::enquote(str!(""), true), "\"\"");
|
||||||
css::enquote(str!("It's a lovely day, don't you think?"), false),
|
}
|
||||||
"'It\\'s a lovely day, don\\'t you think?'"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_apostrophes_double_quotes() {
|
fn apostrophes_single_quotes() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
css::enquote(str!("It's a lovely day, don't you think?"), true),
|
css::enquote(str!("It's a lovely day, don't you think?"), false),
|
||||||
"\"It's a lovely day, don't you think?\""
|
"'It\\'s a lovely day, don\\'t you think?'"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_feet_and_inches_single_quotes() {
|
fn apostrophes_double_quotes() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
css::enquote(str!("5'2\", 6'5\""), false),
|
css::enquote(str!("It's a lovely day, don't you think?"), true),
|
||||||
"'5\\'2\", 6\\'5\"'"
|
"\"It's a lovely day, don't you think?\""
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_feet_and_inches_double_quotes() {
|
fn feet_and_inches_single_quotes() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
css::enquote(str!("5'2\", 6'5\""), true),
|
css::enquote(str!("5'2\", 6'5\""), false),
|
||||||
"\"5'2\\\", 6'5\\\"\""
|
"'5\\'2\", 6\\'5\"'"
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn feet_and_inches_double_quotes() {
|
||||||
|
assert_eq!(
|
||||||
|
css::enquote(str!("5'2\", 6'5\""), true),
|
||||||
|
"\"5'2\\\", 6'5\\\"\""
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
use crate::html;
|
|
||||||
use html5ever::rcdom::{Handle, NodeData};
|
|
||||||
|
|
||||||
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
||||||
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
||||||
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
||||||
|
@ -8,42 +5,48 @@ use html5ever::rcdom::{Handle, NodeData};
|
||||||
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn get_node_name() {
|
mod passing {
|
||||||
let html = "<!doctype html><html><HEAD></HEAD><body><div><P></P></div></body></html>";
|
use crate::html;
|
||||||
let dom = html::html_to_dom(&html);
|
use html5ever::rcdom::{Handle, NodeData};
|
||||||
let mut count = 0;
|
|
||||||
|
|
||||||
fn test_walk(node: &Handle, i: &mut i8) {
|
#[test]
|
||||||
*i += 1;
|
fn get_node_name() {
|
||||||
|
let html = "<!doctype html><html><HEAD></HEAD><body><div><P></P></div></body></html>";
|
||||||
|
let dom = html::html_to_dom(&html);
|
||||||
|
let mut count = 0;
|
||||||
|
|
||||||
match &node.data {
|
fn test_walk(node: &Handle, i: &mut i8) {
|
||||||
NodeData::Document => {
|
*i += 1;
|
||||||
for child in node.children.borrow().iter() {
|
|
||||||
test_walk(child, &mut *i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
NodeData::Element { ref name, .. } => {
|
|
||||||
let node_name = name.local.as_ref().to_string();
|
|
||||||
let parent = html::get_parent_node(node);
|
|
||||||
let parent_node_name = html::get_node_name(&parent);
|
|
||||||
if node_name == "head" || node_name == "body" {
|
|
||||||
assert_eq!(parent_node_name, Some("html"));
|
|
||||||
} else if node_name == "div" {
|
|
||||||
assert_eq!(parent_node_name, Some("body"));
|
|
||||||
} else if node_name == "p" {
|
|
||||||
assert_eq!(parent_node_name, Some("div"));
|
|
||||||
}
|
|
||||||
|
|
||||||
for child in node.children.borrow().iter() {
|
match &node.data {
|
||||||
test_walk(child, &mut *i);
|
NodeData::Document => {
|
||||||
|
for child in node.children.borrow().iter() {
|
||||||
|
test_walk(child, &mut *i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
NodeData::Element { ref name, .. } => {
|
||||||
_ => (),
|
let node_name = name.local.as_ref().to_string();
|
||||||
};
|
let parent = html::get_parent_node(node);
|
||||||
|
let parent_node_name = html::get_node_name(&parent);
|
||||||
|
if node_name == "head" || node_name == "body" {
|
||||||
|
assert_eq!(parent_node_name, Some("html"));
|
||||||
|
} else if node_name == "div" {
|
||||||
|
assert_eq!(parent_node_name, Some("body"));
|
||||||
|
} else if node_name == "p" {
|
||||||
|
assert_eq!(parent_node_name, Some("div"));
|
||||||
|
}
|
||||||
|
|
||||||
|
for child in node.children.borrow().iter() {
|
||||||
|
test_walk(child, &mut *i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
test_walk(&dom.document, &mut count);
|
||||||
|
|
||||||
|
assert_eq!(count, 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
test_walk(&dom.document, &mut count);
|
|
||||||
|
|
||||||
assert_eq!(count, 7);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use crate::html;
|
|
||||||
|
|
||||||
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
||||||
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
||||||
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
||||||
|
@ -7,29 +5,34 @@ use crate::html;
|
||||||
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn passing_icon() {
|
mod passing {
|
||||||
assert!(html::is_icon("icon"));
|
use crate::html;
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_shortcut_icon_capitalized() {
|
fn icon() {
|
||||||
assert!(html::is_icon("Shortcut Icon"));
|
assert!(html::is_icon("icon"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_icon_uppercase() {
|
fn shortcut_icon_capitalized() {
|
||||||
assert!(html::is_icon("ICON"));
|
assert!(html::is_icon("Shortcut Icon"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_mask_icon() {
|
fn icon_uppercase() {
|
||||||
assert!(html::is_icon("mask-icon"));
|
assert!(html::is_icon("ICON"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_fluid_icon() {
|
fn mask_icon() {
|
||||||
assert!(html::is_icon("fluid-icon"));
|
assert!(html::is_icon("mask-icon"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn fluid_icon() {
|
||||||
|
assert!(html::is_icon("fluid-icon"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗
|
// ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗
|
||||||
|
@ -39,12 +42,17 @@ fn passing_fluid_icon() {
|
||||||
// ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn failing_stylesheet() {
|
mod failing {
|
||||||
assert!(!html::is_icon("stylesheet"));
|
use crate::html;
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn failing_empty_string() {
|
fn stylesheet() {
|
||||||
assert!(!html::is_icon(""));
|
assert!(!html::is_icon("stylesheet"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn empty_string() {
|
||||||
|
assert!(!html::is_icon(""));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use crate::html;
|
|
||||||
|
|
||||||
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
||||||
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
||||||
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
||||||
|
@ -7,182 +5,187 @@ use crate::html;
|
||||||
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn passing_div_as_root_element() {
|
mod passing {
|
||||||
let html = "<div><script src=\"some.js\"></script></div>";
|
use crate::html;
|
||||||
let dom = html::html_to_dom(&html);
|
|
||||||
|
|
||||||
let opt_no_css: bool = false;
|
#[test]
|
||||||
let opt_no_frames: bool = false;
|
fn div_as_root_element() {
|
||||||
let opt_no_js: bool = false;
|
let html = "<div><script src=\"some.js\"></script></div>";
|
||||||
let opt_no_images: bool = false;
|
let dom = html::html_to_dom(&html);
|
||||||
let opt_isolate: bool = false;
|
|
||||||
|
|
||||||
assert_eq!(
|
let opt_no_css: bool = false;
|
||||||
html::stringify_document(
|
let opt_no_frames: bool = false;
|
||||||
&dom.document,
|
let opt_no_js: bool = false;
|
||||||
opt_no_css,
|
let opt_no_images: bool = false;
|
||||||
opt_no_frames,
|
let opt_isolate: bool = false;
|
||||||
opt_no_js,
|
|
||||||
opt_no_images,
|
|
||||||
opt_isolate,
|
|
||||||
),
|
|
||||||
"<html><head></head><body><div><script src=\"some.js\"></script></div></body></html>"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
assert_eq!(
|
||||||
fn passing_full_page_with_no_html_head_or_body() {
|
html::stringify_document(
|
||||||
let html = "<title>Isolated document</title>\
|
&dom.document,
|
||||||
<link rel=\"something\" href=\"some.css\" />\
|
opt_no_css,
|
||||||
<meta http-equiv=\"Content-Security-Policy\" content=\"default-src https:\">\
|
opt_no_frames,
|
||||||
<div><script src=\"some.js\"></script></div>";
|
opt_no_js,
|
||||||
let dom = html::html_to_dom(&html);
|
opt_no_images,
|
||||||
|
opt_isolate,
|
||||||
|
),
|
||||||
|
"<html><head></head><body><div><script src=\"some.js\"></script></div></body></html>"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let opt_no_css: bool = false;
|
#[test]
|
||||||
let opt_no_frames: bool = false;
|
fn full_page_with_no_html_head_or_body() {
|
||||||
let opt_no_js: bool = false;
|
let html = "<title>Isolated document</title>\
|
||||||
let opt_no_images: bool = false;
|
<link rel=\"something\" href=\"some.css\" />\
|
||||||
let opt_isolate: bool = true;
|
<meta http-equiv=\"Content-Security-Policy\" content=\"default-src https:\">\
|
||||||
|
<div><script src=\"some.js\"></script></div>";
|
||||||
assert_eq!(
|
let dom = html::html_to_dom(&html);
|
||||||
html::stringify_document(
|
|
||||||
&dom.document,
|
let opt_no_css: bool = false;
|
||||||
opt_no_css,
|
let opt_no_frames: bool = false;
|
||||||
opt_no_frames,
|
let opt_no_js: bool = false;
|
||||||
opt_no_js,
|
let opt_no_images: bool = false;
|
||||||
opt_no_images,
|
let opt_isolate: bool = true;
|
||||||
opt_isolate,
|
|
||||||
),
|
assert_eq!(
|
||||||
"<html>\
|
html::stringify_document(
|
||||||
<head>\
|
&dom.document,
|
||||||
<meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'unsafe-inline' data:;\"></meta>\
|
opt_no_css,
|
||||||
<title>Isolated document</title>\
|
opt_no_frames,
|
||||||
<link rel=\"something\" href=\"some.css\">\
|
opt_no_js,
|
||||||
<meta http-equiv=\"Content-Security-Policy\" content=\"default-src https:\">\
|
opt_no_images,
|
||||||
</head>\
|
opt_isolate,
|
||||||
<body>\
|
),
|
||||||
<div>\
|
"<html>\
|
||||||
<script src=\"some.js\"></script>\
|
<head>\
|
||||||
</div>\
|
<meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'unsafe-inline' data:;\"></meta>\
|
||||||
</body>\
|
<title>Isolated document</title>\
|
||||||
</html>"
|
<link rel=\"something\" href=\"some.css\">\
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn passing_doctype_and_the_rest_no_html_head_or_body() {
|
|
||||||
let html = "<!doctype html>\
|
|
||||||
<title>Unstyled document</title>\
|
|
||||||
<link rel=\"stylesheet\" href=\"main.css\"/>\
|
|
||||||
<div style=\"display: none;\"></div>";
|
|
||||||
let dom = html::html_to_dom(&html);
|
|
||||||
|
|
||||||
let opt_no_css: bool = true;
|
|
||||||
let opt_no_frames: bool = false;
|
|
||||||
let opt_no_js: bool = false;
|
|
||||||
let opt_no_images: bool = false;
|
|
||||||
let opt_isolate: bool = false;
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
html::stringify_document(
|
|
||||||
&dom.document,
|
|
||||||
opt_no_css,
|
|
||||||
opt_no_frames,
|
|
||||||
opt_no_js,
|
|
||||||
opt_no_images,
|
|
||||||
opt_isolate,
|
|
||||||
),
|
|
||||||
"<!DOCTYPE html>\
|
|
||||||
<html>\
|
|
||||||
<head>\
|
|
||||||
<meta http-equiv=\"Content-Security-Policy\" content=\"style-src 'none';\"></meta>\
|
|
||||||
<title>Unstyled document</title>\
|
|
||||||
<link rel=\"stylesheet\" href=\"main.css\">\
|
|
||||||
</head>\
|
|
||||||
<body><div style=\"display: none;\"></div></body>\
|
|
||||||
</html>"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn passing_doctype_and_the_rest_no_html_head_or_body_forbid_frames() {
|
|
||||||
let html = "<!doctype html>\
|
|
||||||
<title>Frameless document</title>\
|
|
||||||
<link rel=\"something\"/>\
|
|
||||||
<div><script src=\"some.js\"></script></div>";
|
|
||||||
let dom = html::html_to_dom(&html);
|
|
||||||
|
|
||||||
let opt_no_css: bool = false;
|
|
||||||
let opt_no_frames: bool = true;
|
|
||||||
let opt_no_js: bool = false;
|
|
||||||
let opt_no_images: bool = false;
|
|
||||||
let opt_isolate: bool = false;
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
html::stringify_document(
|
|
||||||
&dom.document,
|
|
||||||
opt_no_css,
|
|
||||||
opt_no_frames,
|
|
||||||
opt_no_js,
|
|
||||||
opt_no_images,
|
|
||||||
opt_isolate,
|
|
||||||
),
|
|
||||||
"<!DOCTYPE html>\
|
|
||||||
<html>\
|
|
||||||
<head>\
|
|
||||||
<meta http-equiv=\"Content-Security-Policy\" content=\"frame-src 'none';child-src 'none';\"></meta>\
|
|
||||||
<title>Frameless document</title>\
|
|
||||||
<link rel=\"something\">\
|
|
||||||
</head>\
|
|
||||||
<body><div><script src=\"some.js\"></script></div></body>\
|
|
||||||
</html>"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn passing_doctype_and_the_rest_all_forbidden() {
|
|
||||||
let html = "<!doctype html>\
|
|
||||||
<title>no-frame no-css no-js no-image isolated document</title>\
|
|
||||||
<meta http-equiv=\"Content-Security-Policy\" content=\"default-src https:\">\
|
|
||||||
<link rel=\"stylesheet\" href=\"some.css\">\
|
|
||||||
<div>\
|
|
||||||
<script src=\"some.js\"></script>\
|
|
||||||
<img style=\"width: 100%;\" src=\"some.png\" />\
|
|
||||||
<iframe src=\"some.html\"></iframe>\
|
|
||||||
</div>";
|
|
||||||
let dom = html::html_to_dom(&html);
|
|
||||||
|
|
||||||
let opt_isolate: bool = true;
|
|
||||||
let opt_no_css: bool = true;
|
|
||||||
let opt_no_frames: bool = true;
|
|
||||||
let opt_no_js: bool = true;
|
|
||||||
let opt_no_images: bool = true;
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
html::stringify_document(
|
|
||||||
&dom.document,
|
|
||||||
opt_no_css,
|
|
||||||
opt_no_frames,
|
|
||||||
opt_no_js,
|
|
||||||
opt_no_images,
|
|
||||||
opt_isolate,
|
|
||||||
),
|
|
||||||
"<!DOCTYPE html>\
|
|
||||||
<html>\
|
|
||||||
<head>\
|
|
||||||
<meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'unsafe-inline' data:; style-src 'none'; frame-src 'none';child-src 'none'; script-src 'none'; img-src data:;\"></meta>\
|
|
||||||
<title>no-frame no-css no-js no-image isolated document</title>\
|
|
||||||
<meta http-equiv=\"Content-Security-Policy\" content=\"default-src https:\">\
|
<meta http-equiv=\"Content-Security-Policy\" content=\"default-src https:\">\
|
||||||
<link rel=\"stylesheet\" href=\"some.css\">\
|
|
||||||
</head>\
|
</head>\
|
||||||
<body>\
|
<body>\
|
||||||
<div>\
|
<div>\
|
||||||
<script src=\"some.js\"></script>\
|
<script src=\"some.js\"></script>\
|
||||||
<img style=\"width: 100%;\" src=\"some.png\">\
|
|
||||||
<iframe src=\"some.html\"></iframe>\
|
|
||||||
</div>\
|
</div>\
|
||||||
</body>\
|
</body>\
|
||||||
</html>"
|
</html>"
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn doctype_and_the_rest_no_html_head_or_body() {
|
||||||
|
let html = "<!doctype html>\
|
||||||
|
<title>Unstyled document</title>\
|
||||||
|
<link rel=\"stylesheet\" href=\"main.css\"/>\
|
||||||
|
<div style=\"display: none;\"></div>";
|
||||||
|
let dom = html::html_to_dom(&html);
|
||||||
|
|
||||||
|
let opt_no_css: bool = true;
|
||||||
|
let opt_no_frames: bool = false;
|
||||||
|
let opt_no_js: bool = false;
|
||||||
|
let opt_no_images: bool = false;
|
||||||
|
let opt_isolate: bool = false;
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
html::stringify_document(
|
||||||
|
&dom.document,
|
||||||
|
opt_no_css,
|
||||||
|
opt_no_frames,
|
||||||
|
opt_no_js,
|
||||||
|
opt_no_images,
|
||||||
|
opt_isolate,
|
||||||
|
),
|
||||||
|
"<!DOCTYPE html>\
|
||||||
|
<html>\
|
||||||
|
<head>\
|
||||||
|
<meta http-equiv=\"Content-Security-Policy\" content=\"style-src 'none';\"></meta>\
|
||||||
|
<title>Unstyled document</title>\
|
||||||
|
<link rel=\"stylesheet\" href=\"main.css\">\
|
||||||
|
</head>\
|
||||||
|
<body><div style=\"display: none;\"></div></body>\
|
||||||
|
</html>"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn doctype_and_the_rest_no_html_head_or_body_forbid_frames() {
|
||||||
|
let html = "<!doctype html>\
|
||||||
|
<title>Frameless document</title>\
|
||||||
|
<link rel=\"something\"/>\
|
||||||
|
<div><script src=\"some.js\"></script></div>";
|
||||||
|
let dom = html::html_to_dom(&html);
|
||||||
|
|
||||||
|
let opt_no_css: bool = false;
|
||||||
|
let opt_no_frames: bool = true;
|
||||||
|
let opt_no_js: bool = false;
|
||||||
|
let opt_no_images: bool = false;
|
||||||
|
let opt_isolate: bool = false;
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
html::stringify_document(
|
||||||
|
&dom.document,
|
||||||
|
opt_no_css,
|
||||||
|
opt_no_frames,
|
||||||
|
opt_no_js,
|
||||||
|
opt_no_images,
|
||||||
|
opt_isolate,
|
||||||
|
),
|
||||||
|
"<!DOCTYPE html>\
|
||||||
|
<html>\
|
||||||
|
<head>\
|
||||||
|
<meta http-equiv=\"Content-Security-Policy\" content=\"frame-src 'none';child-src 'none';\"></meta>\
|
||||||
|
<title>Frameless document</title>\
|
||||||
|
<link rel=\"something\">\
|
||||||
|
</head>\
|
||||||
|
<body><div><script src=\"some.js\"></script></div></body>\
|
||||||
|
</html>"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn doctype_and_the_rest_all_forbidden() {
|
||||||
|
let html = "<!doctype html>\
|
||||||
|
<title>no-frame no-css no-js no-image isolated document</title>\
|
||||||
|
<meta http-equiv=\"Content-Security-Policy\" content=\"default-src https:\">\
|
||||||
|
<link rel=\"stylesheet\" href=\"some.css\">\
|
||||||
|
<div>\
|
||||||
|
<script src=\"some.js\"></script>\
|
||||||
|
<img style=\"width: 100%;\" src=\"some.png\" />\
|
||||||
|
<iframe src=\"some.html\"></iframe>\
|
||||||
|
</div>";
|
||||||
|
let dom = html::html_to_dom(&html);
|
||||||
|
|
||||||
|
let opt_isolate: bool = true;
|
||||||
|
let opt_no_css: bool = true;
|
||||||
|
let opt_no_frames: bool = true;
|
||||||
|
let opt_no_js: bool = true;
|
||||||
|
let opt_no_images: bool = true;
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
html::stringify_document(
|
||||||
|
&dom.document,
|
||||||
|
opt_no_css,
|
||||||
|
opt_no_frames,
|
||||||
|
opt_no_js,
|
||||||
|
opt_no_images,
|
||||||
|
opt_isolate,
|
||||||
|
),
|
||||||
|
"<!DOCTYPE html>\
|
||||||
|
<html>\
|
||||||
|
<head>\
|
||||||
|
<meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'unsafe-inline' data:; style-src 'none'; frame-src 'none';child-src 'none'; script-src 'none'; img-src data:;\"></meta>\
|
||||||
|
<title>no-frame no-css no-js no-image isolated document</title>\
|
||||||
|
<meta http-equiv=\"Content-Security-Policy\" content=\"default-src https:\">\
|
||||||
|
<link rel=\"stylesheet\" href=\"some.css\">\
|
||||||
|
</head>\
|
||||||
|
<body>\
|
||||||
|
<div>\
|
||||||
|
<script src=\"some.js\"></script>\
|
||||||
|
<img style=\"width: 100%;\" src=\"some.png\">\
|
||||||
|
<iframe src=\"some.html\"></iframe>\
|
||||||
|
</div>\
|
||||||
|
</body>\
|
||||||
|
</html>"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
use crate::html;
|
|
||||||
use html5ever::serialize::{serialize, SerializeOpts};
|
|
||||||
use reqwest::blocking::Client;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
||||||
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
||||||
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
||||||
|
@ -10,410 +5,419 @@ use std::collections::HashMap;
|
||||||
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn passing_basic() {
|
mod passing {
|
||||||
let cache = &mut HashMap::new();
|
use crate::html;
|
||||||
|
use html5ever::serialize::{serialize, SerializeOpts};
|
||||||
|
use reqwest::blocking::Client;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
let html = "<div><P></P></div>";
|
#[test]
|
||||||
let dom = html::html_to_dom(&html);
|
fn basic() {
|
||||||
let url = "http://localhost";
|
let cache = &mut HashMap::new();
|
||||||
|
|
||||||
let opt_no_css: bool = false;
|
let html = "<div><P></P></div>";
|
||||||
let opt_no_fonts: bool = false;
|
let dom = html::html_to_dom(&html);
|
||||||
let opt_no_frames: bool = false;
|
let url = "http://localhost";
|
||||||
let opt_no_js: bool = false;
|
|
||||||
let opt_no_images: bool = false;
|
|
||||||
let opt_silent = true;
|
|
||||||
|
|
||||||
let client = Client::new();
|
let opt_no_css: bool = false;
|
||||||
|
let opt_no_fonts: bool = false;
|
||||||
|
let opt_no_frames: bool = false;
|
||||||
|
let opt_no_js: bool = false;
|
||||||
|
let opt_no_images: bool = false;
|
||||||
|
let opt_silent = true;
|
||||||
|
|
||||||
html::walk_and_embed_assets(
|
let client = Client::new();
|
||||||
cache,
|
|
||||||
&client,
|
|
||||||
&url,
|
|
||||||
&dom.document,
|
|
||||||
opt_no_css,
|
|
||||||
opt_no_fonts,
|
|
||||||
opt_no_frames,
|
|
||||||
opt_no_js,
|
|
||||||
opt_no_images,
|
|
||||||
opt_silent,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut buf: Vec<u8> = Vec::new();
|
html::walk_and_embed_assets(
|
||||||
serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap();
|
cache,
|
||||||
|
&client,
|
||||||
|
&url,
|
||||||
|
&dom.document,
|
||||||
|
opt_no_css,
|
||||||
|
opt_no_fonts,
|
||||||
|
opt_no_frames,
|
||||||
|
opt_no_js,
|
||||||
|
opt_no_images,
|
||||||
|
opt_silent,
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
let mut buf: Vec<u8> = Vec::new();
|
||||||
buf.iter().map(|&c| c as char).collect::<String>(),
|
serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap();
|
||||||
"<html><head></head><body><div><p></p></div></body></html>"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
assert_eq!(
|
||||||
fn passing_ensure_no_recursive_iframe() {
|
buf.iter().map(|&c| c as char).collect::<String>(),
|
||||||
let html = "<div><P></P><iframe src=\"\"></iframe></div>";
|
"<html><head></head><body><div><p></p></div></body></html>"
|
||||||
let dom = html::html_to_dom(&html);
|
);
|
||||||
let url = "http://localhost";
|
}
|
||||||
let cache = &mut HashMap::new();
|
|
||||||
|
|
||||||
let opt_no_css: bool = false;
|
#[test]
|
||||||
let opt_no_fonts: bool = false;
|
fn ensure_no_recursive_iframe() {
|
||||||
let opt_no_frames: bool = false;
|
let html = "<div><P></P><iframe src=\"\"></iframe></div>";
|
||||||
let opt_no_js: bool = false;
|
let dom = html::html_to_dom(&html);
|
||||||
let opt_no_images: bool = false;
|
let url = "http://localhost";
|
||||||
let opt_silent = true;
|
let cache = &mut HashMap::new();
|
||||||
|
|
||||||
let client = Client::new();
|
let opt_no_css: bool = false;
|
||||||
|
let opt_no_fonts: bool = false;
|
||||||
|
let opt_no_frames: bool = false;
|
||||||
|
let opt_no_js: bool = false;
|
||||||
|
let opt_no_images: bool = false;
|
||||||
|
let opt_silent = true;
|
||||||
|
|
||||||
html::walk_and_embed_assets(
|
let client = Client::new();
|
||||||
cache,
|
|
||||||
&client,
|
|
||||||
&url,
|
|
||||||
&dom.document,
|
|
||||||
opt_no_css,
|
|
||||||
opt_no_fonts,
|
|
||||||
opt_no_frames,
|
|
||||||
opt_no_js,
|
|
||||||
opt_no_images,
|
|
||||||
opt_silent,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut buf: Vec<u8> = Vec::new();
|
html::walk_and_embed_assets(
|
||||||
serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap();
|
cache,
|
||||||
|
&client,
|
||||||
|
&url,
|
||||||
|
&dom.document,
|
||||||
|
opt_no_css,
|
||||||
|
opt_no_fonts,
|
||||||
|
opt_no_frames,
|
||||||
|
opt_no_js,
|
||||||
|
opt_no_images,
|
||||||
|
opt_silent,
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
let mut buf: Vec<u8> = Vec::new();
|
||||||
buf.iter().map(|&c| c as char).collect::<String>(),
|
serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap();
|
||||||
"<html><head></head><body><div><p></p><iframe src=\"\"></iframe></div></body></html>"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
assert_eq!(
|
||||||
fn passing_ensure_no_recursive_frame() {
|
buf.iter().map(|&c| c as char).collect::<String>(),
|
||||||
let html = "<frameset><frame src=\"\"></frameset>";
|
"<html><head></head><body><div><p></p><iframe src=\"\"></iframe></div></body></html>"
|
||||||
let dom = html::html_to_dom(&html);
|
);
|
||||||
let url = "http://localhost";
|
}
|
||||||
let cache = &mut HashMap::new();
|
|
||||||
|
|
||||||
let opt_no_css: bool = false;
|
#[test]
|
||||||
let opt_no_fonts: bool = false;
|
fn ensure_no_recursive_frame() {
|
||||||
let opt_no_frames: bool = false;
|
let html = "<frameset><frame src=\"\"></frameset>";
|
||||||
let opt_no_js: bool = false;
|
let dom = html::html_to_dom(&html);
|
||||||
let opt_no_images: bool = false;
|
let url = "http://localhost";
|
||||||
let opt_silent = true;
|
let cache = &mut HashMap::new();
|
||||||
|
|
||||||
let client = Client::new();
|
let opt_no_css: bool = false;
|
||||||
|
let opt_no_fonts: bool = false;
|
||||||
|
let opt_no_frames: bool = false;
|
||||||
|
let opt_no_js: bool = false;
|
||||||
|
let opt_no_images: bool = false;
|
||||||
|
let opt_silent = true;
|
||||||
|
|
||||||
html::walk_and_embed_assets(
|
let client = Client::new();
|
||||||
cache,
|
|
||||||
&client,
|
|
||||||
&url,
|
|
||||||
&dom.document,
|
|
||||||
opt_no_css,
|
|
||||||
opt_no_fonts,
|
|
||||||
opt_no_frames,
|
|
||||||
opt_no_js,
|
|
||||||
opt_no_images,
|
|
||||||
opt_silent,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut buf: Vec<u8> = Vec::new();
|
html::walk_and_embed_assets(
|
||||||
serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap();
|
cache,
|
||||||
|
&client,
|
||||||
|
&url,
|
||||||
|
&dom.document,
|
||||||
|
opt_no_css,
|
||||||
|
opt_no_fonts,
|
||||||
|
opt_no_frames,
|
||||||
|
opt_no_js,
|
||||||
|
opt_no_images,
|
||||||
|
opt_silent,
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
let mut buf: Vec<u8> = Vec::new();
|
||||||
buf.iter().map(|&c| c as char).collect::<String>(),
|
serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap();
|
||||||
"<html><head></head><frameset><frame src=\"\"></frameset></html>"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
assert_eq!(
|
||||||
fn passing_no_css() {
|
buf.iter().map(|&c| c as char).collect::<String>(),
|
||||||
let html = "<link rel=\"stylesheet\" href=\"main.css\">\
|
"<html><head></head><frameset><frame src=\"\"></frameset></html>"
|
||||||
<style>html{background-color: #000;}</style>\
|
);
|
||||||
<div style=\"display: none;\"></div>";
|
}
|
||||||
let dom = html::html_to_dom(&html);
|
|
||||||
let url = "http://localhost";
|
|
||||||
let cache = &mut HashMap::new();
|
|
||||||
|
|
||||||
let opt_no_css: bool = true;
|
#[test]
|
||||||
let opt_no_fonts: bool = false;
|
fn no_css() {
|
||||||
let opt_no_frames: bool = false;
|
let html = "<link rel=\"stylesheet\" href=\"main.css\">\
|
||||||
let opt_no_js: bool = false;
|
<style>html{background-color: #000;}</style>\
|
||||||
let opt_no_images: bool = false;
|
<div style=\"display: none;\"></div>";
|
||||||
let opt_silent = true;
|
let dom = html::html_to_dom(&html);
|
||||||
let client = Client::new();
|
let url = "http://localhost";
|
||||||
|
let cache = &mut HashMap::new();
|
||||||
|
|
||||||
html::walk_and_embed_assets(
|
let opt_no_css: bool = true;
|
||||||
cache,
|
let opt_no_fonts: bool = false;
|
||||||
&client,
|
let opt_no_frames: bool = false;
|
||||||
&url,
|
let opt_no_js: bool = false;
|
||||||
&dom.document,
|
let opt_no_images: bool = false;
|
||||||
opt_no_css,
|
let opt_silent = true;
|
||||||
opt_no_fonts,
|
let client = Client::new();
|
||||||
opt_no_frames,
|
|
||||||
opt_no_js,
|
|
||||||
opt_no_images,
|
|
||||||
opt_silent,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut buf: Vec<u8> = Vec::new();
|
html::walk_and_embed_assets(
|
||||||
serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap();
|
cache,
|
||||||
|
&client,
|
||||||
|
&url,
|
||||||
|
&dom.document,
|
||||||
|
opt_no_css,
|
||||||
|
opt_no_fonts,
|
||||||
|
opt_no_frames,
|
||||||
|
opt_no_js,
|
||||||
|
opt_no_images,
|
||||||
|
opt_silent,
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
let mut buf: Vec<u8> = Vec::new();
|
||||||
buf.iter().map(|&c| c as char).collect::<String>(),
|
serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap();
|
||||||
"<html>\
|
|
||||||
<head>\
|
|
||||||
<link rel=\"stylesheet\">\
|
|
||||||
<style></style>\
|
|
||||||
</head>\
|
|
||||||
<body>\
|
|
||||||
<div></div>\
|
|
||||||
</body>\
|
|
||||||
</html>"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
assert_eq!(
|
||||||
fn passing_no_images() {
|
buf.iter().map(|&c| c as char).collect::<String>(),
|
||||||
let html = "<link rel=\"icon\" href=\"favicon.ico\">\
|
|
||||||
<div><img src=\"http://localhost/assets/mono_lisa.png\" /></div>";
|
|
||||||
let dom = html::html_to_dom(&html);
|
|
||||||
let url = "http://localhost";
|
|
||||||
let cache = &mut HashMap::new();
|
|
||||||
|
|
||||||
let opt_no_css: bool = false;
|
|
||||||
let opt_no_fonts: bool = false;
|
|
||||||
let opt_no_frames: bool = false;
|
|
||||||
let opt_no_js: bool = false;
|
|
||||||
let opt_no_images: bool = true;
|
|
||||||
let opt_silent = true;
|
|
||||||
|
|
||||||
let client = Client::new();
|
|
||||||
|
|
||||||
html::walk_and_embed_assets(
|
|
||||||
cache,
|
|
||||||
&client,
|
|
||||||
&url,
|
|
||||||
&dom.document,
|
|
||||||
opt_no_css,
|
|
||||||
opt_no_fonts,
|
|
||||||
opt_no_frames,
|
|
||||||
opt_no_js,
|
|
||||||
opt_no_images,
|
|
||||||
opt_silent,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut buf: Vec<u8> = Vec::new();
|
|
||||||
serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
buf.iter().map(|&c| c as char).collect::<String>(),
|
|
||||||
format!(
|
|
||||||
"<html>\
|
"<html>\
|
||||||
<head>\
|
<head>\
|
||||||
<link rel=\"icon\">\
|
<link rel=\"stylesheet\">\
|
||||||
</head>\
|
<style></style>\
|
||||||
<body>\
|
</head>\
|
||||||
<div>\
|
<body>\
|
||||||
<img src=\"{empty_image}\">\
|
<div></div>\
|
||||||
</div>\
|
</body>\
|
||||||
</body>\
|
</html>"
|
||||||
</html>",
|
);
|
||||||
empty_image = empty_image!()
|
}
|
||||||
)
|
|
||||||
);
|
#[test]
|
||||||
}
|
fn no_images() {
|
||||||
|
let html = "<link rel=\"icon\" href=\"favicon.ico\">\
|
||||||
#[test]
|
<div><img src=\"http://localhost/assets/mono_lisa.png\" /></div>";
|
||||||
fn passing_no_body_background_images() {
|
let dom = html::html_to_dom(&html);
|
||||||
let html = "<body background=\"no/such/image.png\" background=\"no/such/image2.png\"></body>";
|
let url = "http://localhost";
|
||||||
let dom = html::html_to_dom(&html);
|
let cache = &mut HashMap::new();
|
||||||
let url = "http://localhost";
|
|
||||||
let cache = &mut HashMap::new();
|
let opt_no_css: bool = false;
|
||||||
|
let opt_no_fonts: bool = false;
|
||||||
let opt_no_css: bool = false;
|
let opt_no_frames: bool = false;
|
||||||
let opt_no_fonts: bool = false;
|
let opt_no_js: bool = false;
|
||||||
let opt_no_frames: bool = false;
|
let opt_no_images: bool = true;
|
||||||
let opt_no_js: bool = false;
|
let opt_silent = true;
|
||||||
let opt_no_images: bool = true;
|
|
||||||
let opt_silent = true;
|
let client = Client::new();
|
||||||
|
|
||||||
let client = Client::new();
|
html::walk_and_embed_assets(
|
||||||
|
cache,
|
||||||
html::walk_and_embed_assets(
|
&client,
|
||||||
cache,
|
&url,
|
||||||
&client,
|
&dom.document,
|
||||||
&url,
|
opt_no_css,
|
||||||
&dom.document,
|
opt_no_fonts,
|
||||||
opt_no_css,
|
opt_no_frames,
|
||||||
opt_no_fonts,
|
opt_no_js,
|
||||||
opt_no_frames,
|
opt_no_images,
|
||||||
opt_no_js,
|
opt_silent,
|
||||||
opt_no_images,
|
);
|
||||||
opt_silent,
|
|
||||||
);
|
let mut buf: Vec<u8> = Vec::new();
|
||||||
|
serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap();
|
||||||
let mut buf: Vec<u8> = Vec::new();
|
|
||||||
serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap();
|
assert_eq!(
|
||||||
|
buf.iter().map(|&c| c as char).collect::<String>(),
|
||||||
assert_eq!(
|
format!(
|
||||||
buf.iter().map(|&c| c as char).collect::<String>(),
|
"<html>\
|
||||||
"<html><head></head><body></body></html>"
|
<head>\
|
||||||
);
|
<link rel=\"icon\">\
|
||||||
}
|
</head>\
|
||||||
|
<body>\
|
||||||
#[test]
|
<div>\
|
||||||
fn passing_no_frames() {
|
<img src=\"{empty_image}\">\
|
||||||
let html = "<frameset><frame src=\"http://trackbook.com\"></frameset>";
|
</div>\
|
||||||
let dom = html::html_to_dom(&html);
|
</body>\
|
||||||
let url = "http://localhost";
|
</html>",
|
||||||
let cache = &mut HashMap::new();
|
empty_image = empty_image!()
|
||||||
|
)
|
||||||
let opt_no_css: bool = false;
|
);
|
||||||
let opt_no_fonts: bool = false;
|
}
|
||||||
let opt_no_frames: bool = true;
|
|
||||||
let opt_no_js: bool = false;
|
#[test]
|
||||||
let opt_no_images: bool = false;
|
fn no_body_background_images() {
|
||||||
let opt_silent = true;
|
let html =
|
||||||
let client = Client::new();
|
"<body background=\"no/such/image.png\" background=\"no/such/image2.png\"></body>";
|
||||||
|
let dom = html::html_to_dom(&html);
|
||||||
html::walk_and_embed_assets(
|
let url = "http://localhost";
|
||||||
cache,
|
let cache = &mut HashMap::new();
|
||||||
&client,
|
|
||||||
&url,
|
let opt_no_css: bool = false;
|
||||||
&dom.document,
|
let opt_no_fonts: bool = false;
|
||||||
opt_no_css,
|
let opt_no_frames: bool = false;
|
||||||
opt_no_fonts,
|
let opt_no_js: bool = false;
|
||||||
opt_no_frames,
|
let opt_no_images: bool = true;
|
||||||
opt_no_js,
|
let opt_silent = true;
|
||||||
opt_no_images,
|
|
||||||
opt_silent,
|
let client = Client::new();
|
||||||
);
|
|
||||||
|
html::walk_and_embed_assets(
|
||||||
let mut buf: Vec<u8> = Vec::new();
|
cache,
|
||||||
serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap();
|
&client,
|
||||||
|
&url,
|
||||||
assert_eq!(
|
&dom.document,
|
||||||
buf.iter().map(|&c| c as char).collect::<String>(),
|
opt_no_css,
|
||||||
"<html><head></head><frameset><frame src=\"\"></frameset></html>"
|
opt_no_fonts,
|
||||||
);
|
opt_no_frames,
|
||||||
}
|
opt_no_js,
|
||||||
|
opt_no_images,
|
||||||
#[test]
|
opt_silent,
|
||||||
fn passing_no_iframes() {
|
);
|
||||||
let html = "<iframe src=\"http://trackbook.com\"></iframe>";
|
|
||||||
let dom = html::html_to_dom(&html);
|
let mut buf: Vec<u8> = Vec::new();
|
||||||
let url = "http://localhost";
|
serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap();
|
||||||
let cache = &mut HashMap::new();
|
|
||||||
|
assert_eq!(
|
||||||
let opt_no_css: bool = false;
|
buf.iter().map(|&c| c as char).collect::<String>(),
|
||||||
let opt_no_fonts: bool = false;
|
"<html><head></head><body></body></html>"
|
||||||
let opt_no_frames: bool = true;
|
);
|
||||||
let opt_no_js: bool = false;
|
}
|
||||||
let opt_no_images: bool = false;
|
|
||||||
let opt_silent = true;
|
#[test]
|
||||||
let client = Client::new();
|
fn no_frames() {
|
||||||
|
let html = "<frameset><frame src=\"http://trackbook.com\"></frameset>";
|
||||||
html::walk_and_embed_assets(
|
let dom = html::html_to_dom(&html);
|
||||||
cache,
|
let url = "http://localhost";
|
||||||
&client,
|
let cache = &mut HashMap::new();
|
||||||
&url,
|
|
||||||
&dom.document,
|
let opt_no_css: bool = false;
|
||||||
opt_no_css,
|
let opt_no_fonts: bool = false;
|
||||||
opt_no_fonts,
|
let opt_no_frames: bool = true;
|
||||||
opt_no_frames,
|
let opt_no_js: bool = false;
|
||||||
opt_no_js,
|
let opt_no_images: bool = false;
|
||||||
opt_no_images,
|
let opt_silent = true;
|
||||||
opt_silent,
|
let client = Client::new();
|
||||||
);
|
|
||||||
|
html::walk_and_embed_assets(
|
||||||
let mut buf: Vec<u8> = Vec::new();
|
cache,
|
||||||
serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap();
|
&client,
|
||||||
|
&url,
|
||||||
assert_eq!(
|
&dom.document,
|
||||||
buf.iter().map(|&c| c as char).collect::<String>(),
|
opt_no_css,
|
||||||
"<html><head></head><body><iframe src=\"\"></iframe></body></html>"
|
opt_no_fonts,
|
||||||
);
|
opt_no_frames,
|
||||||
}
|
opt_no_js,
|
||||||
|
opt_no_images,
|
||||||
#[test]
|
opt_silent,
|
||||||
fn passing_no_js() {
|
);
|
||||||
let html = "<div onClick=\"void(0)\">\
|
|
||||||
<script src=\"http://localhost/assets/some.js\"></script>\
|
let mut buf: Vec<u8> = Vec::new();
|
||||||
<script>alert(1)</script>\
|
serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap();
|
||||||
</div>";
|
|
||||||
let dom = html::html_to_dom(&html);
|
assert_eq!(
|
||||||
let url = "http://localhost";
|
buf.iter().map(|&c| c as char).collect::<String>(),
|
||||||
let cache = &mut HashMap::new();
|
"<html><head></head><frameset><frame src=\"\"></frameset></html>"
|
||||||
|
);
|
||||||
let opt_no_css: bool = false;
|
}
|
||||||
let opt_no_fonts: bool = false;
|
|
||||||
let opt_no_frames: bool = false;
|
#[test]
|
||||||
let opt_no_js: bool = true;
|
fn no_iframes() {
|
||||||
let opt_no_images: bool = false;
|
let html = "<iframe src=\"http://trackbook.com\"></iframe>";
|
||||||
let opt_silent = true;
|
let dom = html::html_to_dom(&html);
|
||||||
|
let url = "http://localhost";
|
||||||
let client = Client::new();
|
let cache = &mut HashMap::new();
|
||||||
|
|
||||||
html::walk_and_embed_assets(
|
let opt_no_css: bool = false;
|
||||||
cache,
|
let opt_no_fonts: bool = false;
|
||||||
&client,
|
let opt_no_frames: bool = true;
|
||||||
&url,
|
let opt_no_js: bool = false;
|
||||||
&dom.document,
|
let opt_no_images: bool = false;
|
||||||
opt_no_css,
|
let opt_silent = true;
|
||||||
opt_no_fonts,
|
let client = Client::new();
|
||||||
opt_no_frames,
|
|
||||||
opt_no_js,
|
html::walk_and_embed_assets(
|
||||||
opt_no_images,
|
cache,
|
||||||
opt_silent,
|
&client,
|
||||||
);
|
&url,
|
||||||
|
&dom.document,
|
||||||
let mut buf: Vec<u8> = Vec::new();
|
opt_no_css,
|
||||||
serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap();
|
opt_no_fonts,
|
||||||
|
opt_no_frames,
|
||||||
assert_eq!(
|
opt_no_js,
|
||||||
buf.iter().map(|&c| c as char).collect::<String>(),
|
opt_no_images,
|
||||||
"<html><head></head><body><div><script></script>\
|
opt_silent,
|
||||||
<script></script></div></body></html>"
|
);
|
||||||
);
|
|
||||||
}
|
let mut buf: Vec<u8> = Vec::new();
|
||||||
|
serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap();
|
||||||
#[test]
|
|
||||||
fn passing_with_no_integrity() {
|
assert_eq!(
|
||||||
let html = "<title>No integrity</title>\
|
buf.iter().map(|&c| c as char).collect::<String>(),
|
||||||
<link integrity=\"sha384-...\" rel=\"something\"/>\
|
"<html><head></head><body><iframe src=\"\"></iframe></body></html>"
|
||||||
<script integrity=\"sha384-...\" src=\"some.js\"></script>";
|
);
|
||||||
let dom = html::html_to_dom(&html);
|
}
|
||||||
let url = "http://localhost";
|
|
||||||
let cache = &mut HashMap::new();
|
#[test]
|
||||||
let client = Client::new();
|
fn no_js() {
|
||||||
let opt_no_css: bool = true;
|
let html = "<div onClick=\"void(0)\">\
|
||||||
let opt_no_fonts: bool = false;
|
<script src=\"http://localhost/assets/some.js\"></script>\
|
||||||
let opt_no_frames: bool = true;
|
<script>alert(1)</script>\
|
||||||
let opt_no_js: bool = true;
|
</div>";
|
||||||
let opt_no_images: bool = true;
|
let dom = html::html_to_dom(&html);
|
||||||
let opt_silent = true;
|
let url = "http://localhost";
|
||||||
|
let cache = &mut HashMap::new();
|
||||||
html::walk_and_embed_assets(
|
|
||||||
cache,
|
let opt_no_css: bool = false;
|
||||||
&client,
|
let opt_no_fonts: bool = false;
|
||||||
&url,
|
let opt_no_frames: bool = false;
|
||||||
&dom.document,
|
let opt_no_js: bool = true;
|
||||||
opt_no_css,
|
let opt_no_images: bool = false;
|
||||||
opt_no_fonts,
|
let opt_silent = true;
|
||||||
opt_no_frames,
|
|
||||||
opt_no_js,
|
let client = Client::new();
|
||||||
opt_no_images,
|
|
||||||
opt_silent,
|
html::walk_and_embed_assets(
|
||||||
);
|
cache,
|
||||||
|
&client,
|
||||||
let mut buf: Vec<u8> = Vec::new();
|
&url,
|
||||||
serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap();
|
&dom.document,
|
||||||
|
opt_no_css,
|
||||||
assert_eq!(
|
opt_no_fonts,
|
||||||
buf.iter().map(|&c| c as char).collect::<String>(),
|
opt_no_frames,
|
||||||
"<html>\
|
opt_no_js,
|
||||||
<head><title>No integrity</title><link rel=\"something\"><script></script></head>\
|
opt_no_images,
|
||||||
<body></body>\
|
opt_silent,
|
||||||
</html>"
|
);
|
||||||
);
|
|
||||||
|
let mut buf: Vec<u8> = Vec::new();
|
||||||
|
serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
buf.iter().map(|&c| c as char).collect::<String>(),
|
||||||
|
"<html><head></head><body><div><script></script>\
|
||||||
|
<script></script></div></body></html>"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn with_no_integrity() {
|
||||||
|
let html = "<title>No integrity</title>\
|
||||||
|
<link integrity=\"sha384-...\" rel=\"something\"/>\
|
||||||
|
<script integrity=\"sha384-...\" src=\"some.js\"></script>";
|
||||||
|
let dom = html::html_to_dom(&html);
|
||||||
|
let url = "http://localhost";
|
||||||
|
let cache = &mut HashMap::new();
|
||||||
|
let client = Client::new();
|
||||||
|
let opt_no_css: bool = true;
|
||||||
|
let opt_no_fonts: bool = false;
|
||||||
|
let opt_no_frames: bool = true;
|
||||||
|
let opt_no_js: bool = true;
|
||||||
|
let opt_no_images: bool = true;
|
||||||
|
let opt_silent = true;
|
||||||
|
|
||||||
|
html::walk_and_embed_assets(
|
||||||
|
cache,
|
||||||
|
&client,
|
||||||
|
&url,
|
||||||
|
&dom.document,
|
||||||
|
opt_no_css,
|
||||||
|
opt_no_fonts,
|
||||||
|
opt_no_frames,
|
||||||
|
opt_no_js,
|
||||||
|
opt_no_images,
|
||||||
|
opt_silent,
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut buf: Vec<u8> = Vec::new();
|
||||||
|
serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
buf.iter().map(|&c| c as char).collect::<String>(),
|
||||||
|
"<html>\
|
||||||
|
<head><title>No integrity</title><link rel=\"something\"><script></script></head>\
|
||||||
|
<body></body>\
|
||||||
|
</html>"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use crate::js;
|
|
||||||
|
|
||||||
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
||||||
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
||||||
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
||||||
|
@ -7,19 +5,24 @@ use crate::js;
|
||||||
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn passing_onblur_camelcase() {
|
mod passing {
|
||||||
assert!(js::attr_is_event_handler("onBlur"));
|
use crate::js;
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_onclick_lowercase() {
|
fn onblur_camelcase() {
|
||||||
assert!(js::attr_is_event_handler("onclick"));
|
assert!(js::attr_is_event_handler("onBlur"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_onclick_camelcase() {
|
fn onclick_lowercase() {
|
||||||
assert!(js::attr_is_event_handler("onClick"));
|
assert!(js::attr_is_event_handler("onclick"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn onclick_camelcase() {
|
||||||
|
assert!(js::attr_is_event_handler("onClick"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗
|
// ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗
|
||||||
|
@ -29,17 +32,22 @@ fn passing_onclick_camelcase() {
|
||||||
// ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn failing_href() {
|
mod failing {
|
||||||
assert!(!js::attr_is_event_handler("href"));
|
use crate::js;
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn failing_empty_string() {
|
fn href() {
|
||||||
assert!(!js::attr_is_event_handler(""));
|
assert!(!js::attr_is_event_handler("href"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn failing_class() {
|
fn empty_string() {
|
||||||
assert!(!js::attr_is_event_handler("class"));
|
assert!(!js::attr_is_event_handler(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn class() {
|
||||||
|
assert!(!js::attr_is_event_handler("class"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use crate::utils;
|
|
||||||
|
|
||||||
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
||||||
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
||||||
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
||||||
|
@ -7,42 +5,47 @@ use crate::utils;
|
||||||
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn passing_removes_fragment() {
|
mod passing {
|
||||||
assert_eq!(
|
use crate::utils;
|
||||||
utils::clean_url("https://somewhere.com/font.eot#iefix"),
|
|
||||||
"https://somewhere.com/font.eot"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_removes_empty_fragment() {
|
fn removes_fragment() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
utils::clean_url("https://somewhere.com/font.eot#"),
|
utils::clean_url("https://somewhere.com/font.eot#iefix"),
|
||||||
"https://somewhere.com/font.eot"
|
"https://somewhere.com/font.eot"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_removes_empty_query_and_empty_fragment() {
|
fn removes_empty_fragment() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
utils::clean_url("https://somewhere.com/font.eot?#"),
|
utils::clean_url("https://somewhere.com/font.eot#"),
|
||||||
"https://somewhere.com/font.eot"
|
"https://somewhere.com/font.eot"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_removes_empty_query_amp_and_empty_fragment() {
|
fn removes_empty_query_and_empty_fragment() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
utils::clean_url("https://somewhere.com/font.eot?a=b&#"),
|
utils::clean_url("https://somewhere.com/font.eot?#"),
|
||||||
"https://somewhere.com/font.eot?a=b"
|
"https://somewhere.com/font.eot"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_keeps_credentials() {
|
fn removes_empty_query_amp_and_empty_fragment() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
utils::clean_url("https://cookie:monster@gibson.internet/"),
|
utils::clean_url("https://somewhere.com/font.eot?a=b&#"),
|
||||||
"https://cookie:monster@gibson.internet/"
|
"https://somewhere.com/font.eot?a=b"
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn keeps_credentials() {
|
||||||
|
assert_eq!(
|
||||||
|
utils::clean_url("https://cookie:monster@gibson.internet/"),
|
||||||
|
"https://cookie:monster@gibson.internet/"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use crate::utils;
|
|
||||||
|
|
||||||
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
||||||
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
||||||
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
||||||
|
@ -7,22 +5,27 @@ use crate::utils;
|
||||||
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn passing_encode_string_with_specific_media_type() {
|
mod passing {
|
||||||
let mime = "application/javascript";
|
use crate::utils;
|
||||||
let data = "var word = 'hello';\nalert(word);\n";
|
|
||||||
let data_url = utils::data_to_data_url(mime, data.as_bytes(), "", "");
|
|
||||||
|
|
||||||
assert_eq!(
|
#[test]
|
||||||
&data_url,
|
fn encode_string_with_specific_media_type() {
|
||||||
"data:application/javascript;base64,dmFyIHdvcmQgPSAnaGVsbG8nOwphbGVydCh3b3JkKTsK"
|
let mime = "application/javascript";
|
||||||
);
|
let data = "var word = 'hello';\nalert(word);\n";
|
||||||
}
|
let data_url = utils::data_to_data_url(mime, data.as_bytes(), "", "");
|
||||||
|
|
||||||
#[test]
|
assert_eq!(
|
||||||
fn passing_encode_append_fragment() {
|
&data_url,
|
||||||
let data = "<svg></svg>\n";
|
"data:application/javascript;base64,dmFyIHdvcmQgPSAnaGVsbG8nOwphbGVydCh3b3JkKTsK"
|
||||||
let data_url = utils::data_to_data_url("text/css", data.as_bytes(), "", "fragment");
|
);
|
||||||
|
}
|
||||||
assert_eq!(&data_url, "data:text/css;base64,PHN2Zz48L3N2Zz4K#fragment");
|
|
||||||
|
#[test]
|
||||||
|
fn encode_append_fragment() {
|
||||||
|
let data = "<svg></svg>\n";
|
||||||
|
let data_url = utils::data_to_data_url("text/css", data.as_bytes(), "", "fragment");
|
||||||
|
|
||||||
|
assert_eq!(&data_url, "data:text/css;base64,PHN2Zz48L3N2Zz4K#fragment");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use crate::utils;
|
|
||||||
|
|
||||||
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
||||||
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
||||||
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
||||||
|
@ -7,76 +5,82 @@ use crate::utils;
|
||||||
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn passing_parse_text_html_base64() {
|
mod passing {
|
||||||
let (media_type, data) = utils::data_url_to_data("data:text/html;base64,V29yayBleHBhbmRzIHNvIGFzIHRvIGZpbGwgdGhlIHRpbWUgYXZhaWxhYmxlIGZvciBpdHMgY29tcGxldGlvbg==");
|
use crate::utils;
|
||||||
|
|
||||||
assert_eq!(media_type, "text/html");
|
#[test]
|
||||||
assert_eq!(
|
fn parse_text_html_base64() {
|
||||||
String::from_utf8_lossy(&data),
|
let (media_type, data) = utils::data_url_to_data("data:text/html;base64,V29yayBleHBhbmRzIHNvIGFzIHRvIGZpbGwgdGhlIHRpbWUgYXZhaWxhYmxlIGZvciBpdHMgY29tcGxldGlvbg==");
|
||||||
"Work expands so as to fill the time available for its completion"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
assert_eq!(media_type, "text/html");
|
||||||
fn passing_parse_text_html_utf8() {
|
assert_eq!(
|
||||||
let (media_type, data) = utils::data_url_to_data(
|
String::from_utf8_lossy(&data),
|
||||||
"data:text/html;utf8,Work expands so as to fill the time available for its completion",
|
"Work expands so as to fill the time available for its completion"
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
assert_eq!(media_type, "text/html");
|
#[test]
|
||||||
assert_eq!(
|
fn parse_text_html_utf8() {
|
||||||
String::from_utf8_lossy(&data),
|
let (media_type, data) = utils::data_url_to_data(
|
||||||
"Work expands so as to fill the time available for its completion"
|
"data:text/html;utf8,Work expands so as to fill the time available for its completion",
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
assert_eq!(media_type, "text/html");
|
||||||
fn passing_parse_text_html_plaintext() {
|
assert_eq!(
|
||||||
let (media_type, data) = utils::data_url_to_data(
|
String::from_utf8_lossy(&data),
|
||||||
"data:text/html,Work expands so as to fill the time available for its completion",
|
"Work expands so as to fill the time available for its completion"
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
assert_eq!(media_type, "text/html");
|
#[test]
|
||||||
assert_eq!(
|
fn parse_text_html_plaintext() {
|
||||||
String::from_utf8_lossy(&data),
|
let (media_type, data) = utils::data_url_to_data(
|
||||||
"Work expands so as to fill the time available for its completion"
|
"data:text/html,Work expands so as to fill the time available for its completion",
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
assert_eq!(media_type, "text/html");
|
||||||
fn passing_parse_text_html_charset_utf_8_between_two_whitespaces() {
|
assert_eq!(
|
||||||
let (media_type, data) = utils::data_url_to_data(" data:text/html;charset=utf-8,Work expands so as to fill the time available for its completion ");
|
String::from_utf8_lossy(&data),
|
||||||
|
"Work expands so as to fill the time available for its completion"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
assert_eq!(media_type, "text/html");
|
#[test]
|
||||||
assert_eq!(
|
fn parse_text_html_charset_utf_8_between_two_whitespaces() {
|
||||||
String::from_utf8_lossy(&data),
|
let (media_type, data) = utils::data_url_to_data(" data:text/html;charset=utf-8,Work expands so as to fill the time available for its completion ");
|
||||||
"Work expands so as to fill the time available for its completion"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
assert_eq!(media_type, "text/html");
|
||||||
fn passing_parse_text_css_url_encoded() {
|
assert_eq!(
|
||||||
let (media_type, data) = utils::data_url_to_data("data:text/css,div{background-color:%23000}");
|
String::from_utf8_lossy(&data),
|
||||||
|
"Work expands so as to fill the time available for its completion"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
assert_eq!(media_type, "text/css");
|
#[test]
|
||||||
assert_eq!(String::from_utf8_lossy(&data), "div{background-color:#000}");
|
fn parse_text_css_url_encoded() {
|
||||||
}
|
let (media_type, data) =
|
||||||
|
utils::data_url_to_data("data:text/css,div{background-color:%23000}");
|
||||||
|
|
||||||
#[test]
|
assert_eq!(media_type, "text/css");
|
||||||
fn passing_parse_no_media_type_base64() {
|
assert_eq!(String::from_utf8_lossy(&data), "div{background-color:#000}");
|
||||||
let (media_type, data) = utils::data_url_to_data("data:;base64,dGVzdA==");
|
}
|
||||||
|
|
||||||
assert_eq!(media_type, "");
|
#[test]
|
||||||
assert_eq!(String::from_utf8_lossy(&data), "test");
|
fn parse_no_media_type_base64() {
|
||||||
}
|
let (media_type, data) = utils::data_url_to_data("data:;base64,dGVzdA==");
|
||||||
|
|
||||||
#[test]
|
assert_eq!(media_type, "");
|
||||||
fn passing_parse_no_media_type_no_encoding() {
|
assert_eq!(String::from_utf8_lossy(&data), "test");
|
||||||
let (media_type, data) = utils::data_url_to_data("data:;,test%20test");
|
}
|
||||||
|
|
||||||
assert_eq!(media_type, "");
|
#[test]
|
||||||
assert_eq!(String::from_utf8_lossy(&data), "test test");
|
fn parse_no_media_type_no_encoding() {
|
||||||
|
let (media_type, data) = utils::data_url_to_data("data:;,test%20test");
|
||||||
|
|
||||||
|
assert_eq!(media_type, "");
|
||||||
|
assert_eq!(String::from_utf8_lossy(&data), "test test");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗
|
// ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗
|
||||||
|
@ -86,10 +90,15 @@ fn passing_parse_no_media_type_no_encoding() {
|
||||||
// ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn failing_just_word_data() {
|
mod failing {
|
||||||
let (media_type, data) = utils::data_url_to_data("data");
|
use crate::utils;
|
||||||
|
|
||||||
assert_eq!(media_type, "");
|
#[test]
|
||||||
assert_eq!(String::from_utf8_lossy(&data), "");
|
fn just_word_data() {
|
||||||
|
let (media_type, data) = utils::data_url_to_data("data");
|
||||||
|
|
||||||
|
assert_eq!(media_type, "");
|
||||||
|
assert_eq!(String::from_utf8_lossy(&data), "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use crate::utils;
|
|
||||||
|
|
||||||
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
||||||
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
||||||
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
||||||
|
@ -7,131 +5,136 @@ use crate::utils;
|
||||||
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn passing_image_gif87() {
|
mod passing {
|
||||||
assert_eq!(utils::detect_media_type(b"GIF87a", ""), "image/gif");
|
use crate::utils;
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_image_gif89() {
|
fn image_gif87() {
|
||||||
assert_eq!(utils::detect_media_type(b"GIF89a", ""), "image/gif");
|
assert_eq!(utils::detect_media_type(b"GIF87a", ""), "image/gif");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_image_jpeg() {
|
fn image_gif89() {
|
||||||
assert_eq!(utils::detect_media_type(b"\xFF\xD8\xFF", ""), "image/jpeg");
|
assert_eq!(utils::detect_media_type(b"GIF89a", ""), "image/gif");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_image_png() {
|
fn image_jpeg() {
|
||||||
assert_eq!(
|
assert_eq!(utils::detect_media_type(b"\xFF\xD8\xFF", ""), "image/jpeg");
|
||||||
utils::detect_media_type(b"\x89PNG\x0D\x0A\x1A\x0A", ""),
|
}
|
||||||
"image/png"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_image_svg() {
|
fn image_png() {
|
||||||
assert_eq!(utils::detect_media_type(b"<svg ", ""), "image/svg+xml");
|
assert_eq!(
|
||||||
}
|
utils::detect_media_type(b"\x89PNG\x0D\x0A\x1A\x0A", ""),
|
||||||
|
"image/png"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_image_webp() {
|
fn image_svg() {
|
||||||
assert_eq!(
|
assert_eq!(utils::detect_media_type(b"<svg ", ""), "image/svg+xml");
|
||||||
utils::detect_media_type(b"RIFF....WEBPVP8 ", ""),
|
}
|
||||||
"image/webp"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_image_icon() {
|
fn image_webp() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
utils::detect_media_type(b"\x00\x00\x01\x00", ""),
|
utils::detect_media_type(b"RIFF....WEBPVP8 ", ""),
|
||||||
"image/x-icon"
|
"image/webp"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_image_svg_filename() {
|
fn image_icon() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
utils::detect_media_type(b"<?xml ", "local-file.svg"),
|
utils::detect_media_type(b"\x00\x00\x01\x00", ""),
|
||||||
"image/svg+xml"
|
"image/x-icon"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_image_svg_url_uppercase() {
|
fn image_svg_filename() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
utils::detect_media_type(b"", "https://some-site.com/images/local-file.SVG"),
|
utils::detect_media_type(b"<?xml ", "local-file.svg"),
|
||||||
"image/svg+xml"
|
"image/svg+xml"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_audio_mpeg() {
|
fn image_svg_url_uppercase() {
|
||||||
assert_eq!(utils::detect_media_type(b"ID3", ""), "audio/mpeg");
|
assert_eq!(
|
||||||
}
|
utils::detect_media_type(b"", "https://some-site.com/images/local-file.SVG"),
|
||||||
|
"image/svg+xml"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_audio_mpeg_2() {
|
fn audio_mpeg() {
|
||||||
assert_eq!(utils::detect_media_type(b"\xFF\x0E", ""), "audio/mpeg");
|
assert_eq!(utils::detect_media_type(b"ID3", ""), "audio/mpeg");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_audio_mpeg_3() {
|
fn audio_mpeg_2() {
|
||||||
assert_eq!(utils::detect_media_type(b"\xFF\x0F", ""), "audio/mpeg");
|
assert_eq!(utils::detect_media_type(b"\xFF\x0E", ""), "audio/mpeg");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_audio_ogg() {
|
fn audio_mpeg_3() {
|
||||||
assert_eq!(utils::detect_media_type(b"OggS", ""), "audio/ogg");
|
assert_eq!(utils::detect_media_type(b"\xFF\x0F", ""), "audio/mpeg");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_audio_wav() {
|
fn audio_ogg() {
|
||||||
assert_eq!(
|
assert_eq!(utils::detect_media_type(b"OggS", ""), "audio/ogg");
|
||||||
utils::detect_media_type(b"RIFF....WAVEfmt ", ""),
|
}
|
||||||
"audio/wav"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_audio_flac() {
|
fn audio_wav() {
|
||||||
assert_eq!(utils::detect_media_type(b"fLaC", ""), "audio/x-flac");
|
assert_eq!(
|
||||||
}
|
utils::detect_media_type(b"RIFF....WAVEfmt ", ""),
|
||||||
|
"audio/wav"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_video_avi() {
|
fn audio_flac() {
|
||||||
assert_eq!(
|
assert_eq!(utils::detect_media_type(b"fLaC", ""), "audio/x-flac");
|
||||||
utils::detect_media_type(b"RIFF....AVI LIST", ""),
|
}
|
||||||
"video/avi"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_video_mp4() {
|
fn video_avi() {
|
||||||
assert_eq!(utils::detect_media_type(b"....ftyp", ""), "video/mp4");
|
assert_eq!(
|
||||||
}
|
utils::detect_media_type(b"RIFF....AVI LIST", ""),
|
||||||
|
"video/avi"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_video_mpeg() {
|
fn video_mp4() {
|
||||||
assert_eq!(
|
assert_eq!(utils::detect_media_type(b"....ftyp", ""), "video/mp4");
|
||||||
utils::detect_media_type(b"\x00\x00\x01\x0B", ""),
|
}
|
||||||
"video/mpeg"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_video_quicktime() {
|
fn video_mpeg() {
|
||||||
assert_eq!(utils::detect_media_type(b"....moov", ""), "video/quicktime");
|
assert_eq!(
|
||||||
}
|
utils::detect_media_type(b"\x00\x00\x01\x0B", ""),
|
||||||
|
"video/mpeg"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_video_webm() {
|
fn video_quicktime() {
|
||||||
assert_eq!(
|
assert_eq!(utils::detect_media_type(b"....moov", ""), "video/quicktime");
|
||||||
utils::detect_media_type(b"\x1A\x45\xDF\xA3", ""),
|
}
|
||||||
"video/webm"
|
|
||||||
);
|
#[test]
|
||||||
|
fn video_webm() {
|
||||||
|
assert_eq!(
|
||||||
|
utils::detect_media_type(b"\x1A\x45\xDF\xA3", ""),
|
||||||
|
"video/webm"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗
|
// ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗
|
||||||
|
@ -141,7 +144,12 @@ fn passing_video_webm() {
|
||||||
// ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn failing_unknown_media_type() {
|
mod failing {
|
||||||
assert_eq!(utils::detect_media_type(b"abcdef0123456789", ""), "");
|
use crate::utils;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn unknown_media_type() {
|
||||||
|
assert_eq!(utils::detect_media_type(b"abcdef0123456789", ""), "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use crate::utils;
|
|
||||||
|
|
||||||
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
||||||
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
||||||
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
||||||
|
@ -7,32 +5,37 @@ use crate::utils;
|
||||||
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn passing_remove_protocl_and_fragment() {
|
mod passing {
|
||||||
if cfg!(windows) {
|
use crate::utils;
|
||||||
assert_eq!(
|
|
||||||
utils::file_url_to_fs_path("file:///C:/documents/some-path/some-file.svg#fragment"),
|
|
||||||
"C:\\documents\\some-path\\some-file.svg"
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
assert_eq!(
|
|
||||||
utils::file_url_to_fs_path("file:///tmp/some-path/some-file.svg#fragment"),
|
|
||||||
"/tmp/some-path/some-file.svg"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_decodes_urls() {
|
fn remove_protocl_and_fragment() {
|
||||||
if cfg!(windows) {
|
if cfg!(windows) {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
utils::file_url_to_fs_path("file:///C:/Documents%20and%20Settings/some-file.html"),
|
utils::file_url_to_fs_path("file:///C:/documents/some-path/some-file.svg#fragment"),
|
||||||
"C:\\Documents and Settings\\some-file.html"
|
"C:\\documents\\some-path\\some-file.svg"
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
utils::file_url_to_fs_path("file:///home/user/My%20Documents"),
|
utils::file_url_to_fs_path("file:///tmp/some-path/some-file.svg#fragment"),
|
||||||
"/home/user/My Documents"
|
"/tmp/some-path/some-file.svg"
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn decodes_urls() {
|
||||||
|
if cfg!(windows) {
|
||||||
|
assert_eq!(
|
||||||
|
utils::file_url_to_fs_path("file:///C:/Documents%20and%20Settings/some-file.html"),
|
||||||
|
"C:\\Documents and Settings\\some-file.html"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
assert_eq!(
|
||||||
|
utils::file_url_to_fs_path("file:///home/user/My%20Documents"),
|
||||||
|
"/home/user/My Documents"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use crate::utils;
|
|
||||||
|
|
||||||
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
||||||
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
||||||
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
||||||
|
@ -7,17 +5,22 @@ use crate::utils;
|
||||||
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn passing_data_url() {
|
mod passing {
|
||||||
assert_eq!(
|
use crate::utils;
|
||||||
utils::get_url_fragment(
|
|
||||||
"data:image/svg+xml;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h#test"
|
|
||||||
),
|
|
||||||
"test"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_https_empty() {
|
fn data_url() {
|
||||||
assert_eq!(utils::get_url_fragment("https://kernel.org#"), "");
|
assert_eq!(
|
||||||
|
utils::get_url_fragment(
|
||||||
|
"data:image/svg+xml;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h#test"
|
||||||
|
),
|
||||||
|
"test"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn https_empty() {
|
||||||
|
assert_eq!(utils::get_url_fragment("https://kernel.org#"), "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use crate::utils;
|
|
||||||
|
|
||||||
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
||||||
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
||||||
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
||||||
|
@ -7,18 +5,23 @@ use crate::utils;
|
||||||
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn passing_data_url_text_html() {
|
mod passing {
|
||||||
assert!(utils::is_data_url(
|
use crate::utils;
|
||||||
"data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h"
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_data_url_no_media_type() {
|
fn data_url_text_html() {
|
||||||
assert!(utils::is_data_url(
|
assert!(utils::is_data_url(
|
||||||
"data:;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h"
|
"data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h"
|
||||||
));
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn data_url_no_media_type() {
|
||||||
|
assert!(utils::is_data_url(
|
||||||
|
"data:;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h"
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗
|
// ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗
|
||||||
|
@ -28,17 +31,22 @@ fn passing_data_url_no_media_type() {
|
||||||
// ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn failing_https_url() {
|
mod failing {
|
||||||
assert!(!utils::is_data_url("https://kernel.org"));
|
use crate::utils;
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn failing_no_protocol_url() {
|
fn https_url() {
|
||||||
assert!(!utils::is_data_url("//kernel.org"));
|
assert!(!utils::is_data_url("https://kernel.org"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn failing_empty_string() {
|
fn no_protocol_url() {
|
||||||
assert!(!utils::is_data_url(""));
|
assert!(!utils::is_data_url("//kernel.org"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn empty_string() {
|
||||||
|
assert!(!utils::is_data_url(""));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use crate::utils;
|
|
||||||
|
|
||||||
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
||||||
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
||||||
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
||||||
|
@ -7,32 +5,37 @@ use crate::utils;
|
||||||
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn passing_unix_file_url() {
|
mod passing {
|
||||||
assert!(utils::is_file_url(
|
use crate::utils;
|
||||||
"file:///home/user/Websites/my-website/index.html"
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_windows_file_url() {
|
fn unix_file_url() {
|
||||||
assert!(utils::is_file_url(
|
assert!(utils::is_file_url(
|
||||||
"file:///C:/Documents%20and%20Settings/user/Websites/my-website/assets/images/logo.png"
|
"file:///home/user/Websites/my-website/index.html"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_unix_url_with_backslashes() {
|
fn windows_file_url() {
|
||||||
assert!(utils::is_file_url(
|
assert!(utils::is_file_url(
|
||||||
"file:\\\\\\home\\user\\Websites\\my-website\\index.html"
|
"file:///C:/Documents%20and%20Settings/user/Websites/my-website/assets/images/logo.png"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_windows_file_url_with_backslashes() {
|
fn unix_url_with_backslashes() {
|
||||||
assert!(utils::is_file_url(
|
assert!(utils::is_file_url(
|
||||||
"file:\\\\\\C:\\Documents%20and%20Settings\\user\\Websites\\my-website\\assets\\images\\logo.png"
|
"file:\\\\\\home\\user\\Websites\\my-website\\index.html"
|
||||||
));
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn windows_file_url_with_backslashes() {
|
||||||
|
assert!(utils::is_file_url(
|
||||||
|
"file:\\\\\\C:\\Documents%20and%20Settings\\user\\Websites\\my-website\\assets\\images\\logo.png"
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗
|
// ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗
|
||||||
|
@ -42,34 +45,39 @@ fn passing_windows_file_url_with_backslashes() {
|
||||||
// ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn failing_url_with_no_protocl() {
|
mod failing {
|
||||||
assert!(!utils::is_file_url("//kernel.org"));
|
use crate::utils;
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn failing_dot_slash_filename() {
|
fn url_with_no_protocl() {
|
||||||
assert!(!utils::is_file_url("./index.html"));
|
assert!(!utils::is_file_url("//kernel.org"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn failing_just_filename() {
|
fn dot_slash_filename() {
|
||||||
assert!(!utils::is_file_url("some-local-page.htm"));
|
assert!(!utils::is_file_url("./index.html"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn failing_https_ip_port_url() {
|
fn just_filename() {
|
||||||
assert!(!utils::is_file_url("https://1.2.3.4:80/www/index.html"));
|
assert!(!utils::is_file_url("some-local-page.htm"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn failing_data_url() {
|
fn https_ip_port_url() {
|
||||||
assert!(!utils::is_file_url(
|
assert!(!utils::is_file_url("https://1.2.3.4:80/www/index.html"));
|
||||||
"data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h"
|
}
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn failing_just_word_file() {
|
fn data_url() {
|
||||||
assert!(!utils::is_file_url("file"));
|
assert!(!utils::is_file_url(
|
||||||
|
"data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn just_word_file() {
|
||||||
|
assert!(!utils::is_file_url("file"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use crate::utils;
|
|
||||||
|
|
||||||
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
||||||
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
||||||
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
||||||
|
@ -7,19 +5,24 @@ use crate::utils;
|
||||||
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn passing_http_url() {
|
mod passing {
|
||||||
assert!(utils::is_http_url("http://kernel.org"));
|
use crate::utils;
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_https_url() {
|
fn http_url() {
|
||||||
assert!(utils::is_http_url("https://www.rust-lang.org/"));
|
assert!(utils::is_http_url("http://kernel.org"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_http_url_with_backslashes() {
|
fn https_url() {
|
||||||
assert!(utils::is_http_url("http:\\\\freebsd.org\\"));
|
assert!(utils::is_http_url("https://www.rust-lang.org/"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn http_url_with_backslashes() {
|
||||||
|
assert!(utils::is_http_url("http:\\\\freebsd.org\\"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗
|
// ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗
|
||||||
|
@ -29,29 +32,34 @@ fn passing_http_url_with_backslashes() {
|
||||||
// ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn failing_url_with_no_protocol() {
|
mod failing {
|
||||||
assert!(!utils::is_http_url("//kernel.org"));
|
use crate::utils;
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn failing_dot_slash_filename() {
|
fn url_with_no_protocol() {
|
||||||
assert!(!utils::is_http_url("./index.html"));
|
assert!(!utils::is_http_url("//kernel.org"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn failing_just_filename() {
|
fn dot_slash_filename() {
|
||||||
assert!(!utils::is_http_url("some-local-page.htm"));
|
assert!(!utils::is_http_url("./index.html"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn failing_https_ip_port_url() {
|
fn just_filename() {
|
||||||
assert!(!utils::is_http_url("ftp://1.2.3.4/www/index.html"));
|
assert!(!utils::is_http_url("some-local-page.htm"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn failing_data_url() {
|
fn https_ip_port_url() {
|
||||||
assert!(!utils::is_http_url(
|
assert!(!utils::is_http_url("ftp://1.2.3.4/www/index.html"));
|
||||||
"data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h"
|
}
|
||||||
));
|
|
||||||
|
#[test]
|
||||||
|
fn data_url() {
|
||||||
|
assert!(!utils::is_http_url(
|
||||||
|
"data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h"
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
use url::ParseError;
|
|
||||||
|
|
||||||
use crate::utils;
|
|
||||||
|
|
||||||
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
||||||
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
||||||
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
||||||
|
@ -9,203 +5,210 @@ use crate::utils;
|
||||||
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn passing_from_https_to_level_up_relative() -> Result<(), ParseError> {
|
mod passing {
|
||||||
let resolved_url = utils::resolve_url("https://www.kernel.org", "../category/signatures.html")?;
|
use crate::utils;
|
||||||
|
use url::ParseError;
|
||||||
|
|
||||||
assert_eq!(
|
#[test]
|
||||||
resolved_url.as_str(),
|
fn from_https_to_level_up_relative() -> Result<(), ParseError> {
|
||||||
"https://www.kernel.org/category/signatures.html"
|
let resolved_url =
|
||||||
);
|
utils::resolve_url("https://www.kernel.org", "../category/signatures.html")?;
|
||||||
|
|
||||||
Ok(())
|
assert_eq!(
|
||||||
}
|
resolved_url.as_str(),
|
||||||
|
"https://www.kernel.org/category/signatures.html"
|
||||||
|
);
|
||||||
|
|
||||||
#[test]
|
Ok(())
|
||||||
fn passing_from_just_filename_to_full_https_url() -> Result<(), ParseError> {
|
}
|
||||||
let resolved_url = utils::resolve_url(
|
|
||||||
"saved_page.htm",
|
|
||||||
"https://www.kernel.org/category/signatures.html",
|
|
||||||
)?;
|
|
||||||
|
|
||||||
assert_eq!(
|
#[test]
|
||||||
resolved_url.as_str(),
|
fn from_just_filename_to_full_https_url() -> Result<(), ParseError> {
|
||||||
"https://www.kernel.org/category/signatures.html"
|
let resolved_url = utils::resolve_url(
|
||||||
);
|
"saved_page.htm",
|
||||||
|
"https://www.kernel.org/category/signatures.html",
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(())
|
assert_eq!(
|
||||||
}
|
resolved_url.as_str(),
|
||||||
|
"https://www.kernel.org/category/signatures.html"
|
||||||
|
);
|
||||||
|
|
||||||
#[test]
|
Ok(())
|
||||||
fn passing_from_https_url_to_url_with_no_protocol() -> Result<(), ParseError> {
|
}
|
||||||
let resolved_url = utils::resolve_url(
|
|
||||||
"https://www.kernel.org",
|
|
||||||
"//www.kernel.org/theme/images/logos/tux.png",
|
|
||||||
)?;
|
|
||||||
|
|
||||||
assert_eq!(
|
#[test]
|
||||||
resolved_url.as_str(),
|
fn from_https_url_to_url_with_no_protocol() -> Result<(), ParseError> {
|
||||||
"https://www.kernel.org/theme/images/logos/tux.png"
|
let resolved_url = utils::resolve_url(
|
||||||
);
|
"https://www.kernel.org",
|
||||||
|
"//www.kernel.org/theme/images/logos/tux.png",
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(())
|
assert_eq!(
|
||||||
}
|
resolved_url.as_str(),
|
||||||
|
"https://www.kernel.org/theme/images/logos/tux.png"
|
||||||
|
);
|
||||||
|
|
||||||
#[test]
|
Ok(())
|
||||||
fn passing_from_https_url_to_url_with_no_protocol_and_on_different_hostname(
|
}
|
||||||
) -> Result<(), ParseError> {
|
|
||||||
let resolved_url = utils::resolve_url(
|
|
||||||
"https://www.kernel.org",
|
|
||||||
"//another-host.org/theme/images/logos/tux.png",
|
|
||||||
)?;
|
|
||||||
|
|
||||||
assert_eq!(
|
#[test]
|
||||||
resolved_url.as_str(),
|
fn from_https_url_to_url_with_no_protocol_and_on_different_hostname() -> Result<(), ParseError>
|
||||||
"https://another-host.org/theme/images/logos/tux.png"
|
{
|
||||||
);
|
let resolved_url = utils::resolve_url(
|
||||||
|
"https://www.kernel.org",
|
||||||
|
"//another-host.org/theme/images/logos/tux.png",
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(())
|
assert_eq!(
|
||||||
}
|
resolved_url.as_str(),
|
||||||
|
"https://another-host.org/theme/images/logos/tux.png"
|
||||||
|
);
|
||||||
|
|
||||||
#[test]
|
Ok(())
|
||||||
fn passing_from_https_url_to_relative_root_path() -> Result<(), ParseError> {
|
}
|
||||||
let resolved_url = utils::resolve_url(
|
|
||||||
"https://www.kernel.org/category/signatures.html",
|
|
||||||
"/theme/images/logos/tux.png",
|
|
||||||
)?;
|
|
||||||
|
|
||||||
assert_eq!(
|
#[test]
|
||||||
resolved_url.as_str(),
|
fn from_https_url_to_relative_root_path() -> Result<(), ParseError> {
|
||||||
"https://www.kernel.org/theme/images/logos/tux.png"
|
let resolved_url = utils::resolve_url(
|
||||||
);
|
"https://www.kernel.org/category/signatures.html",
|
||||||
|
"/theme/images/logos/tux.png",
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(())
|
assert_eq!(
|
||||||
}
|
resolved_url.as_str(),
|
||||||
|
"https://www.kernel.org/theme/images/logos/tux.png"
|
||||||
|
);
|
||||||
|
|
||||||
#[test]
|
Ok(())
|
||||||
fn passing_from_https_to_just_filename() -> Result<(), ParseError> {
|
}
|
||||||
let resolved_url = utils::resolve_url(
|
|
||||||
"https://www.w3schools.com/html/html_iframe.asp",
|
|
||||||
"default.asp",
|
|
||||||
)?;
|
|
||||||
|
|
||||||
assert_eq!(
|
#[test]
|
||||||
resolved_url.as_str(),
|
fn from_https_to_just_filename() -> Result<(), ParseError> {
|
||||||
"https://www.w3schools.com/html/default.asp"
|
let resolved_url = utils::resolve_url(
|
||||||
);
|
"https://www.w3schools.com/html/html_iframe.asp",
|
||||||
|
"default.asp",
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(())
|
assert_eq!(
|
||||||
}
|
resolved_url.as_str(),
|
||||||
|
"https://www.w3schools.com/html/default.asp"
|
||||||
|
);
|
||||||
|
|
||||||
#[test]
|
Ok(())
|
||||||
fn passing_from_data_url_to_https() -> Result<(), ParseError> {
|
}
|
||||||
let resolved_url = utils::resolve_url(
|
|
||||||
"data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h",
|
|
||||||
"https://www.kernel.org/category/signatures.html",
|
|
||||||
)?;
|
|
||||||
|
|
||||||
assert_eq!(
|
#[test]
|
||||||
resolved_url.as_str(),
|
fn from_data_url_to_https() -> Result<(), ParseError> {
|
||||||
"https://www.kernel.org/category/signatures.html"
|
let resolved_url = utils::resolve_url(
|
||||||
);
|
"data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h",
|
||||||
|
"https://www.kernel.org/category/signatures.html",
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(())
|
assert_eq!(
|
||||||
}
|
resolved_url.as_str(),
|
||||||
|
"https://www.kernel.org/category/signatures.html"
|
||||||
|
);
|
||||||
|
|
||||||
#[test]
|
Ok(())
|
||||||
fn passing_from_data_url_to_data_url() -> Result<(), ParseError> {
|
}
|
||||||
let resolved_url = utils::resolve_url(
|
|
||||||
"data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h",
|
|
||||||
"data:text/html;base64,PGEgaHJlZj0iaW5kZXguaHRtbCI+SG9tZTwvYT4K",
|
|
||||||
)?;
|
|
||||||
|
|
||||||
assert_eq!(
|
#[test]
|
||||||
resolved_url.as_str(),
|
fn from_data_url_to_data_url() -> Result<(), ParseError> {
|
||||||
"data:text/html;base64,PGEgaHJlZj0iaW5kZXguaHRtbCI+SG9tZTwvYT4K"
|
let resolved_url = utils::resolve_url(
|
||||||
);
|
"data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h",
|
||||||
|
"data:text/html;base64,PGEgaHJlZj0iaW5kZXguaHRtbCI+SG9tZTwvYT4K",
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(())
|
assert_eq!(
|
||||||
}
|
resolved_url.as_str(),
|
||||||
|
"data:text/html;base64,PGEgaHJlZj0iaW5kZXguaHRtbCI+SG9tZTwvYT4K"
|
||||||
|
);
|
||||||
|
|
||||||
#[test]
|
Ok(())
|
||||||
fn passing_from_file_url_to_relative_path() -> Result<(), ParseError> {
|
}
|
||||||
let resolved_url = utils::resolve_url(
|
|
||||||
"file:///home/user/Websites/my-website/index.html",
|
|
||||||
"assets/images/logo.png",
|
|
||||||
)
|
|
||||||
.unwrap_or(str!());
|
|
||||||
|
|
||||||
assert_eq!(
|
#[test]
|
||||||
resolved_url.as_str(),
|
fn from_file_url_to_relative_path() -> Result<(), ParseError> {
|
||||||
"file:///home/user/Websites/my-website/assets/images/logo.png"
|
let resolved_url = utils::resolve_url(
|
||||||
);
|
"file:///home/user/Websites/my-website/index.html",
|
||||||
|
"assets/images/logo.png",
|
||||||
|
)
|
||||||
|
.unwrap_or(str!());
|
||||||
|
|
||||||
Ok(())
|
assert_eq!(
|
||||||
}
|
resolved_url.as_str(),
|
||||||
|
"file:///home/user/Websites/my-website/assets/images/logo.png"
|
||||||
|
);
|
||||||
|
|
||||||
#[test]
|
Ok(())
|
||||||
fn passing_from_file_url_to_relative_path_with_backslashes() -> Result<(), ParseError> {
|
}
|
||||||
let resolved_url = utils::resolve_url(
|
|
||||||
"file:\\\\\\home\\user\\Websites\\my-website\\index.html",
|
|
||||||
"assets\\images\\logo.png",
|
|
||||||
)
|
|
||||||
.unwrap_or(str!());
|
|
||||||
|
|
||||||
assert_eq!(
|
#[test]
|
||||||
resolved_url.as_str(),
|
fn from_file_url_to_relative_path_with_backslashes() -> Result<(), ParseError> {
|
||||||
"file:///home/user/Websites/my-website/assets/images/logo.png"
|
let resolved_url = utils::resolve_url(
|
||||||
);
|
"file:\\\\\\home\\user\\Websites\\my-website\\index.html",
|
||||||
|
"assets\\images\\logo.png",
|
||||||
|
)
|
||||||
|
.unwrap_or(str!());
|
||||||
|
|
||||||
Ok(())
|
assert_eq!(
|
||||||
}
|
resolved_url.as_str(),
|
||||||
|
"file:///home/user/Websites/my-website/assets/images/logo.png"
|
||||||
|
);
|
||||||
|
|
||||||
#[test]
|
Ok(())
|
||||||
fn passing_from_data_url_to_file_url() -> Result<(), ParseError> {
|
}
|
||||||
let resolved_url = utils::resolve_url(
|
|
||||||
"data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h",
|
|
||||||
"file:///etc/passwd",
|
|
||||||
)
|
|
||||||
.unwrap_or(str!());
|
|
||||||
|
|
||||||
assert_eq!(resolved_url.as_str(), "file:///etc/passwd");
|
#[test]
|
||||||
|
fn from_data_url_to_file_url() -> Result<(), ParseError> {
|
||||||
|
let resolved_url = utils::resolve_url(
|
||||||
|
"data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h",
|
||||||
|
"file:///etc/passwd",
|
||||||
|
)
|
||||||
|
.unwrap_or(str!());
|
||||||
|
|
||||||
Ok(())
|
assert_eq!(resolved_url.as_str(), "file:///etc/passwd");
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
Ok(())
|
||||||
fn passing_preserve_fragment() -> Result<(), ParseError> {
|
}
|
||||||
let resolved_url = utils::resolve_url(
|
|
||||||
"http://doesnt-matter.local/",
|
|
||||||
"css/fonts/fontmarvelous.svg#fontmarvelous",
|
|
||||||
)
|
|
||||||
.unwrap_or(str!());
|
|
||||||
|
|
||||||
assert_eq!(
|
#[test]
|
||||||
resolved_url.as_str(),
|
fn preserve_fragment() -> Result<(), ParseError> {
|
||||||
"http://doesnt-matter.local/css/fonts/fontmarvelous.svg#fontmarvelous"
|
let resolved_url = utils::resolve_url(
|
||||||
);
|
"http://doesnt-matter.local/",
|
||||||
|
"css/fonts/fontmarvelous.svg#fontmarvelous",
|
||||||
|
)
|
||||||
|
.unwrap_or(str!());
|
||||||
|
|
||||||
Ok(())
|
assert_eq!(
|
||||||
}
|
resolved_url.as_str(),
|
||||||
|
"http://doesnt-matter.local/css/fonts/fontmarvelous.svg#fontmarvelous"
|
||||||
|
);
|
||||||
|
|
||||||
#[test]
|
Ok(())
|
||||||
fn passing_resolve_from_file_url_to_file_url() -> Result<(), ParseError> {
|
}
|
||||||
let resolved_url = if cfg!(windows) {
|
|
||||||
utils::resolve_url("file:///c:/index.html", "file:///c:/image.png").unwrap_or(str!())
|
|
||||||
} else {
|
|
||||||
utils::resolve_url("file:///tmp/index.html", "file:///tmp/image.png").unwrap_or(str!())
|
|
||||||
};
|
|
||||||
|
|
||||||
assert_eq!(
|
#[test]
|
||||||
resolved_url.as_str(),
|
fn resolve_from_file_url_to_file_url() -> Result<(), ParseError> {
|
||||||
if cfg!(windows) {
|
let resolved_url = if cfg!(windows) {
|
||||||
"file:///c:/image.png"
|
utils::resolve_url("file:///c:/index.html", "file:///c:/image.png").unwrap_or(str!())
|
||||||
} else {
|
} else {
|
||||||
"file:///tmp/image.png"
|
utils::resolve_url("file:///tmp/index.html", "file:///tmp/image.png").unwrap_or(str!())
|
||||||
}
|
};
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
assert_eq!(
|
||||||
|
resolved_url.as_str(),
|
||||||
|
if cfg!(windows) {
|
||||||
|
"file:///c:/image.png"
|
||||||
|
} else {
|
||||||
|
"file:///tmp/image.png"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗
|
// ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗
|
||||||
|
@ -215,15 +218,21 @@ fn passing_resolve_from_file_url_to_file_url() -> Result<(), ParseError> {
|
||||||
// ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn failing_from_data_url_to_url_with_no_protocol() -> Result<(), ParseError> {
|
mod failing {
|
||||||
let resolved_url = utils::resolve_url(
|
use crate::utils;
|
||||||
"data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h",
|
use url::ParseError;
|
||||||
"//www.w3schools.com/html/html_iframe.asp",
|
|
||||||
)
|
|
||||||
.unwrap_or(str!());
|
|
||||||
|
|
||||||
assert_eq!(resolved_url.as_str(), "");
|
#[test]
|
||||||
|
fn from_data_url_to_url_with_no_protocol() -> Result<(), ParseError> {
|
||||||
|
let resolved_url = utils::resolve_url(
|
||||||
|
"data:text/html;base64,V2VsY29tZSBUbyBUaGUgUGFydHksIDxiPlBhbDwvYj4h",
|
||||||
|
"//www.w3schools.com/html/html_iframe.asp",
|
||||||
|
)
|
||||||
|
.unwrap_or(str!());
|
||||||
|
|
||||||
Ok(())
|
assert_eq!(resolved_url.as_str(), "");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
use crate::utils;
|
|
||||||
use reqwest::blocking::Client;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::env;
|
|
||||||
|
|
||||||
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
||||||
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
||||||
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
||||||
|
@ -10,66 +5,74 @@ use std::env;
|
||||||
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn passing_read_data_url() {
|
mod passing {
|
||||||
let cache = &mut HashMap::new();
|
use crate::utils;
|
||||||
let client = Client::new();
|
use reqwest::blocking::Client;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::env;
|
||||||
|
|
||||||
// If both source and target are data URLs,
|
#[test]
|
||||||
// ensure the result contains target data URL
|
fn read_data_url() {
|
||||||
let (data, final_url, media_type) = utils::retrieve_asset(
|
let cache = &mut HashMap::new();
|
||||||
cache,
|
let client = Client::new();
|
||||||
&client,
|
|
||||||
"data:text/html;base64,c291cmNl",
|
|
||||||
"data:text/html;base64,dGFyZ2V0",
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
utils::data_to_data_url(&media_type, &data, &final_url, ""),
|
|
||||||
utils::data_to_data_url("text/html", "target".as_bytes(), "", "")
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
final_url,
|
|
||||||
utils::data_to_data_url("text/html", "target".as_bytes(), "", "")
|
|
||||||
);
|
|
||||||
assert_eq!(&media_type, "text/html");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
// If both source and target are data URLs,
|
||||||
fn passing_read_local_file_with_file_url_parent() {
|
// ensure the result contains target data URL
|
||||||
let cache = &mut HashMap::new();
|
let (data, final_url, media_type) = utils::retrieve_asset(
|
||||||
let client = Client::new();
|
cache,
|
||||||
|
&client,
|
||||||
let file_url_protocol: &str = if cfg!(windows) { "file:///" } else { "file://" };
|
"data:text/html;base64,c291cmNl",
|
||||||
|
"data:text/html;base64,dGFyZ2V0",
|
||||||
// Inclusion of local assets from local sources should be allowed
|
false,
|
||||||
let cwd = env::current_dir().unwrap();
|
|
||||||
let (data, final_url, _media_type) = utils::retrieve_asset(
|
|
||||||
cache,
|
|
||||||
&client,
|
|
||||||
&format!(
|
|
||||||
"{file}{cwd}/src/tests/data/basic/local-file.html",
|
|
||||||
file = file_url_protocol,
|
|
||||||
cwd = cwd.to_str().unwrap()
|
|
||||||
),
|
|
||||||
&format!(
|
|
||||||
"{file}{cwd}/src/tests/data/basic/local-script.js",
|
|
||||||
file = file_url_protocol,
|
|
||||||
cwd = cwd.to_str().unwrap()
|
|
||||||
),
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
assert_eq!(utils::data_to_data_url("application/javascript", &data, &final_url, ""), "data:application/javascript;base64,ZG9jdW1lbnQuYm9keS5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSAiZ3JlZW4iOwpkb2N1bWVudC5ib2R5LnN0eWxlLmNvbG9yID0gInJlZCI7Cg==");
|
|
||||||
assert_eq!(
|
|
||||||
&final_url,
|
|
||||||
&format!(
|
|
||||||
"{file}{cwd}/src/tests/data/basic/local-script.js",
|
|
||||||
file = file_url_protocol,
|
|
||||||
cwd = cwd.to_str().unwrap()
|
|
||||||
)
|
)
|
||||||
);
|
.unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
utils::data_to_data_url(&media_type, &data, &final_url, ""),
|
||||||
|
utils::data_to_data_url("text/html", "target".as_bytes(), "", "")
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
final_url,
|
||||||
|
utils::data_to_data_url("text/html", "target".as_bytes(), "", "")
|
||||||
|
);
|
||||||
|
assert_eq!(&media_type, "text/html");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn read_local_file_with_file_url_parent() {
|
||||||
|
let cache = &mut HashMap::new();
|
||||||
|
let client = Client::new();
|
||||||
|
|
||||||
|
let file_url_protocol: &str = if cfg!(windows) { "file:///" } else { "file://" };
|
||||||
|
|
||||||
|
// Inclusion of local assets from local sources should be allowed
|
||||||
|
let cwd = env::current_dir().unwrap();
|
||||||
|
let (data, final_url, _media_type) = utils::retrieve_asset(
|
||||||
|
cache,
|
||||||
|
&client,
|
||||||
|
&format!(
|
||||||
|
"{file}{cwd}/src/tests/data/basic/local-file.html",
|
||||||
|
file = file_url_protocol,
|
||||||
|
cwd = cwd.to_str().unwrap()
|
||||||
|
),
|
||||||
|
&format!(
|
||||||
|
"{file}{cwd}/src/tests/data/basic/local-script.js",
|
||||||
|
file = file_url_protocol,
|
||||||
|
cwd = cwd.to_str().unwrap()
|
||||||
|
),
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(utils::data_to_data_url("application/javascript", &data, &final_url, ""), "data:application/javascript;base64,ZG9jdW1lbnQuYm9keS5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSAiZ3JlZW4iOwpkb2N1bWVudC5ib2R5LnN0eWxlLmNvbG9yID0gInJlZCI7Cg==");
|
||||||
|
assert_eq!(
|
||||||
|
&final_url,
|
||||||
|
&format!(
|
||||||
|
"{file}{cwd}/src/tests/data/basic/local-script.js",
|
||||||
|
file = file_url_protocol,
|
||||||
|
cwd = cwd.to_str().unwrap()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗
|
// ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗
|
||||||
|
@ -79,46 +82,53 @@ fn passing_read_local_file_with_file_url_parent() {
|
||||||
// ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn failing_read_local_file_with_data_url_parent() {
|
mod failing {
|
||||||
let cache = &mut HashMap::new();
|
use crate::utils;
|
||||||
let client = Client::new();
|
use reqwest::blocking::Client;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
// Inclusion of local assets from data URL sources should not be allowed
|
#[test]
|
||||||
match utils::retrieve_asset(
|
fn read_local_file_with_data_url_parent() {
|
||||||
cache,
|
let cache = &mut HashMap::new();
|
||||||
&client,
|
let client = Client::new();
|
||||||
"data:text/html;base64,SoUrCe",
|
|
||||||
"file:///etc/passwd",
|
// Inclusion of local assets from data URL sources should not be allowed
|
||||||
false,
|
match utils::retrieve_asset(
|
||||||
) {
|
cache,
|
||||||
Ok((..)) => {
|
&client,
|
||||||
assert!(false);
|
"data:text/html;base64,SoUrCe",
|
||||||
|
"file:///etc/passwd",
|
||||||
|
false,
|
||||||
|
) {
|
||||||
|
Ok((..)) => {
|
||||||
|
assert!(false);
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
assert!(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(_) => {
|
}
|
||||||
assert!(true);
|
|
||||||
}
|
#[test]
|
||||||
}
|
fn read_local_file_with_https_parent() {
|
||||||
}
|
let cache = &mut HashMap::new();
|
||||||
|
let client = Client::new();
|
||||||
#[test]
|
|
||||||
fn failing_read_local_file_with_https_parent() {
|
// Inclusion of local assets from remote sources should not be allowed
|
||||||
let cache = &mut HashMap::new();
|
match utils::retrieve_asset(
|
||||||
let client = Client::new();
|
cache,
|
||||||
|
&client,
|
||||||
// Inclusion of local assets from remote sources should not be allowed
|
"https://kernel.org/",
|
||||||
match utils::retrieve_asset(
|
"file:///etc/passwd",
|
||||||
cache,
|
false,
|
||||||
&client,
|
) {
|
||||||
"https://kernel.org/",
|
Ok((..)) => {
|
||||||
"file:///etc/passwd",
|
assert!(false);
|
||||||
false,
|
}
|
||||||
) {
|
Err(_) => {
|
||||||
Ok((..)) => {
|
assert!(true);
|
||||||
assert!(false);
|
}
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
assert!(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use crate::utils;
|
|
||||||
|
|
||||||
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
// ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗
|
||||||
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
|
||||||
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
// ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗
|
||||||
|
@ -7,50 +5,55 @@ use crate::utils;
|
||||||
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn passing_mailto() {
|
mod passing {
|
||||||
assert!(utils::url_has_protocol(
|
use crate::utils;
|
||||||
"mailto:somebody@somewhere.com?subject=hello"
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_tel() {
|
fn mailto() {
|
||||||
assert!(utils::url_has_protocol("tel:5551234567"));
|
assert!(utils::url_has_protocol(
|
||||||
}
|
"mailto:somebody@somewhere.com?subject=hello"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_ftp_no_slashes() {
|
fn tel() {
|
||||||
assert!(utils::url_has_protocol("ftp:some-ftp-server.com"));
|
assert!(utils::url_has_protocol("tel:5551234567"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_ftp_with_credentials() {
|
fn ftp_no_slashes() {
|
||||||
assert!(utils::url_has_protocol(
|
assert!(utils::url_has_protocol("ftp:some-ftp-server.com"));
|
||||||
"ftp://user:password@some-ftp-server.com"
|
}
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_javascript() {
|
fn ftp_with_credentials() {
|
||||||
assert!(utils::url_has_protocol("javascript:void(0)"));
|
assert!(utils::url_has_protocol(
|
||||||
}
|
"ftp://user:password@some-ftp-server.com"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_http() {
|
fn javascript() {
|
||||||
assert!(utils::url_has_protocol("http://news.ycombinator.com"));
|
assert!(utils::url_has_protocol("javascript:void(0)"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_https() {
|
fn http() {
|
||||||
assert!(utils::url_has_protocol("https://github.com"));
|
assert!(utils::url_has_protocol("http://news.ycombinator.com"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn passing_mailto_uppercase() {
|
fn https() {
|
||||||
assert!(utils::url_has_protocol(
|
assert!(utils::url_has_protocol("https://github.com"));
|
||||||
"MAILTO:somebody@somewhere.com?subject=hello"
|
}
|
||||||
));
|
|
||||||
|
#[test]
|
||||||
|
fn mailto_uppercase() {
|
||||||
|
assert!(utils::url_has_protocol(
|
||||||
|
"MAILTO:somebody@somewhere.com?subject=hello"
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗
|
// ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗
|
||||||
|
@ -60,24 +63,29 @@ fn passing_mailto_uppercase() {
|
||||||
// ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝
|
// ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝
|
||||||
// ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
// ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn failing_url_with_no_protocol() {
|
mod failing {
|
||||||
assert!(!utils::url_has_protocol(
|
use crate::utils;
|
||||||
"//some-hostname.com/some-file.html"
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn failing_relative_path() {
|
fn url_with_no_protocol() {
|
||||||
assert!(!utils::url_has_protocol("some-hostname.com/some-file.html"));
|
assert!(!utils::url_has_protocol(
|
||||||
}
|
"//some-hostname.com/some-file.html"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn failing_relative_to_root_path() {
|
fn relative_path() {
|
||||||
assert!(!utils::url_has_protocol("/some-file.html"));
|
assert!(!utils::url_has_protocol("some-hostname.com/some-file.html"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn failing_empty_string() {
|
fn relative_to_root_path() {
|
||||||
assert!(!utils::url_has_protocol(""));
|
assert!(!utils::url_has_protocol("/some-file.html"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn empty_string() {
|
||||||
|
assert!(!utils::url_has_protocol(""));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue