Annotation For tests/utils.rs
Logged in as anonymous

Origin for each line in tests/utils.rs from check-in 98c5a42df0:

dd307557e6 2026-07-31        arcade: use smtp2tg::utils::{
dd307557e6 2026-07-31        arcade: 	validate,
dd307557e6 2026-07-31        arcade: 	RE_CLOSING,
dd307557e6 2026-07-31        arcade: 	RE_DOMAIN,
dd307557e6 2026-07-31        arcade: };
6e7d1e877b 2026-07-31        arcade: 
6e7d1e877b 2026-07-31        arcade: use std::{
6e7d1e877b 2026-07-31        arcade: 	borrow::Cow,
6e7d1e877b 2026-07-31        arcade: 	mem::discriminant,
6e7d1e877b 2026-07-31        arcade: };
6e7d1e877b 2026-07-31        arcade: 
98c5a42df0 2026-08-01        arcade: use stacked_errors::{
98c5a42df0 2026-08-01        arcade: 	Result,
98c5a42df0 2026-08-01        arcade: 	ensure_eq,
98c5a42df0 2026-08-01        arcade: };
6e7d1e877b 2026-07-31        arcade: 
6e7d1e877b 2026-07-31        arcade: #[test]
6e7d1e877b 2026-07-31        arcade: fn test_validate_escaping_behavior () -> Result<()> {
6e7d1e877b 2026-07-31        arcade: 	let cases: &[(&str, Cow<str>)] = &[
6e7d1e877b 2026-07-31        arcade: 		// `validate` escapes HTML special characters.
6e7d1e877b 2026-07-31        arcade: 		("<p>Some <b>valid</b> HTML</p>", Cow::Owned("&lt;p&gt;Some &lt;b&gt;valid&lt;/b&gt; HTML&lt;/p&gt;".into())),
6e7d1e877b 2026-07-31        arcade: 		// Empty input is returned unchanged.
6e7d1e877b 2026-07-31        arcade: 		("", Cow::Borrowed("")),
6e7d1e877b 2026-07-31        arcade: 		// Whitespace-only input needs no escaping.
6e7d1e877b 2026-07-31        arcade: 		("   \t\n", Cow::Borrowed("   \t\n")),
6e7d1e877b 2026-07-31        arcade: 		// `validate` returns `Cow<'a, str>` borrowed from its input lifetime `'a`.
6e7d1e877b 2026-07-31        arcade: 		// These two cases exercise both branches of that `Cow` to make sure the
6e7d1e877b 2026-07-31        arcade: 		// explicit lifetime introduced on `validate` still lets callers observe a
6e7d1e877b 2026-07-31        arcade: 		// zero-copy borrow when no escaping is required.
6e7d1e877b 2026-07-31        arcade: 		("plain text without special html characters", Cow::Borrowed("plain text without special html characters")),
6e7d1e877b 2026-07-31        arcade: 		("5 > 3 & 2 < 4", Cow::Owned("5 &gt; 3 &amp; 2 &lt; 4".into())),
6e7d1e877b 2026-07-31        arcade: 	];
6e7d1e877b 2026-07-31        arcade: 	for (input, expected) in cases {
6e7d1e877b 2026-07-31        arcade: 		let result = validate(input)?;
98c5a42df0 2026-08-01        arcade: 		ensure_eq!(&result, expected, format!("unexpected output for input {input:?}"));
98c5a42df0 2026-08-01        arcade: 		ensure_eq!(discriminant(&result), discriminant(expected), format!("wrong Cow variant for input {input:?}"));
6e7d1e877b 2026-07-31        arcade: 	}
6e7d1e877b 2026-07-31        arcade: 	Ok(())
6e7d1e877b 2026-07-31        arcade: }
6e7d1e877b 2026-07-31        arcade: 
6e7d1e877b 2026-07-31        arcade: #[test]
98c5a42df0 2026-08-01        arcade: fn test_validate_closing_tag_behavior () -> Result<()> {
6e7d1e877b 2026-07-31        arcade: 	let cases = [
6e7d1e877b 2026-07-31        arcade: 		("</  pre  >", true),
6e7d1e877b 2026-07-31        arcade: 		("</\tcode\t>", true),
6e7d1e877b 2026-07-31        arcade: 		("</b>", false),
6e7d1e877b 2026-07-31        arcade: 		("</Code>", true),
6e7d1e877b 2026-07-31        arcade: 		("</code>", true),
6e7d1e877b 2026-07-31        arcade: 		("</code>\t", true),
6e7d1e877b 2026-07-31        arcade: 		("</code>\t>", true),
6e7d1e877b 2026-07-31        arcade: 		("</div>", false), // Not a pre/code tag
6e7d1e877b 2026-07-31        arcade: 		("</PRE>", true),
6e7d1e877b 2026-07-31        arcade: 		("</pre>", true),
6e7d1e877b 2026-07-31        arcade: 		("</pre>\n", true),
6e7d1e877b 2026-07-31        arcade: 		("<p>Some <b>valid</b> HTML</p></code><a href='http://somewere.com'>Link injection!</a>", true),
6e7d1e877b 2026-07-31        arcade: 		("<pre>", false),
6e7d1e877b 2026-07-31        arcade: 	];
6e7d1e877b 2026-07-31        arcade: 	for (input, expected) in cases {
98c5a42df0 2026-08-01        arcade: 		ensure_eq!(RE_CLOSING.is_match(input), expected, format!("unexpected match result for {input:?}"));
6e7d1e877b 2026-07-31        arcade: 	}
98c5a42df0 2026-08-01        arcade: 	Ok(())
6e7d1e877b 2026-07-31        arcade: }
6e7d1e877b 2026-07-31        arcade: 
6e7d1e877b 2026-07-31        arcade: #[test]
98c5a42df0 2026-08-01        arcade: fn test_regex_domain_behavior() -> Result<()> {
6e7d1e877b 2026-07-31        arcade: 	let cases = [
6e7d1e877b 2026-07-31        arcade: 		("", false),
6e7d1e877b 2026-07-31        arcade: 		("-example.com", false),
6e7d1e877b 2026-07-31        arcade: 		(".example.com", false),
6e7d1e877b 2026-07-31        arcade: 		("123.456", true),
6e7d1e877b 2026-07-31        arcade: 		("EXAMPLE.COM", false),
6e7d1e877b 2026-07-31        arcade: 		("a", true),
6e7d1e877b 2026-07-31        arcade: 		("a.b", true),
6e7d1e877b 2026-07-31        arcade: 		("example-.com", false),
6e7d1e877b 2026-07-31        arcade: 		("example..com", false),
6e7d1e877b 2026-07-31        arcade: 		("example.com", true),
6e7d1e877b 2026-07-31        arcade: 		("example.com.", false),
6e7d1e877b 2026-07-31        arcade: 		("invalid@domain.com", false),
6e7d1e877b 2026-07-31        arcade: 		("my-host.example.com", true),
6e7d1e877b 2026-07-31        arcade: 		("sub.example.co.uk", true),
6e7d1e877b 2026-07-31        arcade: 	];
6e7d1e877b 2026-07-31        arcade: 	for (input, expected) in cases {
98c5a42df0 2026-08-01        arcade: 		ensure_eq!(RE_DOMAIN.is_match(input), expected, format!("unexpected match result for {input:?}"));
6e7d1e877b 2026-07-31        arcade: 	}
98c5a42df0 2026-08-01        arcade: 	Ok(())
dd307557e6 2026-07-31        arcade: }