use super::{assert_origin_form, parse_graceful, parse_strict};
use crate::uri::ParseError;
#[test]
fn graceful_accepts_unreserved_extras_in_path() {
for s in ["/path{x}", "/p|q", "/p^q", "/p<x>"] {
let u = parse_graceful(s).unwrap();
assert_origin_form(&u, s, None, None);
assert!(
matches!(parse_strict(s), Err(ParseError::StrictViolation)),
"strict should reject {s:?}"
);
}
}
#[test]
fn graceful_accepts_extras_in_query_and_fragment() {
for s in ["/p?key={val}", "/p?ab|cd", "/p#frag^x", "/p#tag<x>"] {
assert!(parse_graceful(s).is_ok(), "graceful should accept {s:?}");
assert!(
matches!(parse_strict(s), Err(ParseError::StrictViolation)),
"strict should reject {s:?}"
);
}
}
#[test]
fn graceful_accepts_high_byte_in_path() {
let s: &[u8] = b"/p\xc3\xa9foo"; crate::uri::Uri::parse(s).unwrap();
assert!(matches!(
crate::uri::Uri::parse_strict(s),
Err(ParseError::StrictViolation)
));
}
#[test]
fn strict_accepts_pchar_path() {
for s in [
"/foo",
"/a/b/c",
"/a-b.c_d~e",
"/a%20b",
"/p:q@r",
"/p?key=val",
] {
assert!(parse_strict(s).is_ok(), "strict should accept {s:?}");
}
}
#[test]
fn strict_accepts_well_formed_absolute() {
for s in [
"http://example.com/",
"https://api.example.com:443/v1/users",
"ftp://ftp.example.org/pub/file.txt",
"ws://chat.example.com/socket",
"urn:isbn:0451450523",
"mailto:user@example.com",
] {
assert!(
parse_strict(s).is_ok(),
"strict should accept {s:?}, got {:?}",
parse_strict(s)
);
}
}
#[test]
fn strict_rejects_non_pchar_in_absolute_path() {
for s in [
"http://example.com/p{x}",
"http://example.com/p|q",
"http://example.com/p^q",
"http://example.com/p<q>",
] {
assert!(
matches!(parse_strict(s), Err(ParseError::StrictViolation)),
"strict must reject {s:?}"
);
}
}
#[test]
fn strict_rejects_non_pchar_in_query_and_fragment() {
for s in ["http://example.com/?p{x}", "http://example.com/#frag|x"] {
assert!(matches!(parse_strict(s), Err(ParseError::StrictViolation)));
}
}
#[test]
fn strict_rejects_bad_percent_encoding_in_path() {
for s in ["/foo%", "/foo%a", "/foo%zz", "/foo%g0"] {
assert!(
matches!(
parse_strict(s),
Err(ParseError::InvalidPercentEncoding { .. })
),
"got {:?} for {s:?}",
parse_strict(s)
);
}
}
#[test]
fn strict_rejects_bad_percent_encoding_in_query_and_fragment() {
assert!(matches!(
parse_strict("/p?bad%"),
Err(ParseError::InvalidPercentEncoding { .. })
));
assert!(matches!(
parse_strict("/p#bad%"),
Err(ParseError::InvalidPercentEncoding { .. })
));
}
#[test]
fn percent_encoded_specials_preserved_in_path() {
for (s, expected_path) in [
("/abc%23def", "/abc%23def"),
("/abc%3Fdef", "/abc%3Fdef"),
("/abc%2Fdef", "/abc%2Fdef"),
] {
let u = parse_graceful(s).unwrap();
assert_origin_form(&u, expected_path, None, None);
}
}
#[test]
fn percent_encoded_specials_preserved_in_query() {
let u = parse_graceful("/p?q=%23anchor").unwrap();
assert_origin_form(&u, "/p", Some("q=%23anchor"), None);
}
#[test]
fn strict_accepts_valid_userinfo_chars() {
for s in [
"http://user@example.com/",
"http://user:pass@example.com/",
"http://a-b.c_d~e@example.com/",
"http://us!er$tag@example.com/",
"http://u(s)e+r,1;2=3@example.com/",
"http://user%40info@example.com/", ] {
assert!(parse_strict(s).is_ok(), "strict should accept {s:?}");
}
}
#[test]
fn strict_rejects_at_in_userinfo() {
let graceful = parse_graceful("http://user@info@example.com/").unwrap();
assert!(!graceful.is_asterisk()); assert!(matches!(
parse_strict("http://user@info@example.com/"),
Err(ParseError::StrictViolation)
));
}
#[test]
fn strict_rejects_non_userinfo_byte_classes() {
for s in [
"http://us{er}@example.com/",
"http://us|er@example.com/",
"http://us<er>@example.com/",
] {
assert!(parse_graceful(s).is_ok(), "graceful should accept {s:?}");
assert!(
matches!(parse_strict(s), Err(ParseError::StrictViolation)),
"strict should reject {s:?}"
);
}
}
#[test]
fn strict_rejects_bad_pct_in_userinfo() {
for s in [
"http://user%@example.com/",
"http://user%z@example.com/",
"http://user%zz@example.com/",
] {
assert!(
matches!(
parse_strict(s),
Err(ParseError::InvalidPercentEncoding { .. })
),
"got {:?} for {s:?}",
parse_strict(s)
);
}
}
#[test]
fn strict_reference_rejects_colon_in_first_path_segment() {
use crate::uri::Uri;
for s in ["1a:b", "a%62:c"] {
assert!(
matches!(
Uri::parse_reference_strict(s),
Err(ParseError::StrictViolation)
),
"strict reference must reject {s:?}, got {:?}",
Uri::parse_reference_strict(s)
);
assert!(
Uri::parse_reference(s).is_ok(),
"graceful reference must accept {s:?}"
);
}
}
#[test]
fn strict_reference_accepts_colon_in_non_first_segment() {
use crate::uri::Uri;
for s in [
"/foo:bar", "./foo:bar", "foo/bar:baz", "?q=foo:bar", "#frag:colon", ] {
Uri::parse_reference_strict(s)
.unwrap_or_else(|e| panic!("strict reference must accept {s:?}, got {e:?}"));
}
}