Skip to main content

max / makenotwork

1.8 KB · 51 lines History Blame Raw
1 //! Property tests for [`super`].
2 use super::*;
3 use proptest::prelude::*;
4
5 const SCOPE: &str = "22222222-2222-2222-2222-222222222222";
6
7 fn policy() -> UrlPolicy {
8 UrlPolicy::new(
9 "https://u.makenot.work/a/p",
10 [
11 "makenot.work".to_string(),
12 "u.makenot.work".to_string(),
13 "cdn.makenot.work".to_string(),
14 ],
15 )
16 .unwrap()
17 }
18
19 proptest! {
20 // Arbitrary input never panics, and the output is always valid CSS
21 // (it re-parses cleanly).
22 #[test]
23 fn never_panics_output_reparses(input in "\\PC{0,400}") {
24 let (out, _rej) = sanitize_css(&input, SCOPE, &policy());
25 prop_assert!(StyleSheet::parse(&out, parser_options()).is_ok(), "invalid output: {out}");
26 }
27
28 // A randomly-built external url() is always neutralized.
29 #[test]
30 fn external_url_always_stripped(host in "[a-z]{3,10}", tld in "(com|net|io|xyz)", path in "[a-z0-9]{1,10}") {
31 let domain = format!("{host}.{tld}");
32 let css = format!(".x {{ background: url(https://{domain}/{path}) }}");
33 let out = sanitize_css(&css, SCOPE, &policy()).0;
34 let leaked = out.contains(&domain);
35 prop_assert!(!leaked, "leaked host: {}", out);
36 }
37
38 // Every non-empty sanitized sheet confines its style rules to the canvas
39 // and ends with the reduced-motion guard.
40 #[test]
41 fn always_scoped_and_guarded(sel in "[a-z][a-z0-9]{0,8}", prop in "(color|background-color|margin)") {
42 let css = format!("{sel} {{ {prop}: inherit }}");
43 let out = sanitize_css(&css, SCOPE, &policy()).0;
44 let scope_tag = format!("uc-{SCOPE}");
45 let has_scope = out.contains(&scope_tag);
46 let has_guard = out.contains("prefers-reduced-motion");
47 prop_assert!(has_scope, "missing scope: {}", out);
48 prop_assert!(has_guard, "missing guard: {}", out);
49 }
50 }
51