= context
.sql
.query_get_value(
context,
"SELECT mime_headers FROM msgs WHERE id=?;",
paramsv![self],
)
.await;
if let Some(rawmime) = rawmime {
match HtmlMsgParser::from_bytes(context, rawmime.as_bytes()).await {
Err(err) => format!("parser error: {}", err),
Ok(parser) => parser.html,
}
} else {
format!("parser error: no mime for {}", self)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::test_utils::*;
#[async_std::test]
async fn test_htmlparse_plain_unspecified() {
let t = TestContext::new().await;
let raw = include_bytes!("../test-data/message/text_plain_unspecified.eml");
let parser = HtmlMsgParser::from_bytes(&t.ctx, raw).await.unwrap();
assert_eq!(
parser.html,
r##"
This message does not have Content-Type nor Subject.
"##
);
}
#[async_std::test]
async fn test_htmlparse_plain_iso88591() {
let t = TestContext::new().await;
let raw = include_bytes!("../test-data/message/text_plain_iso88591.eml");
let parser = HtmlMsgParser::from_bytes(&t.ctx, raw).await.unwrap();
assert_eq!(
parser.html,
r##"
message with a non-UTF-8 encoding: äöüßÄÖÜ
"##
);
}
#[async_std::test]
async fn test_htmlparse_plain_flowed() {
let t = TestContext::new().await;
let raw = include_bytes!("../test-data/message/text_plain_flowed.eml");
let parser = HtmlMsgParser::from_bytes(&t.ctx, raw).await.unwrap();
assert!(parser.plain.unwrap().flowed);
assert_eq!(
parser.html,
r##"
This line ends with a space and will be merged with the next one due to format=flowed.
This line does not end with a space
and will be wrapped as usual.
"##
);
}
#[async_std::test]
async fn test_htmlparse_alt_plain() {
let t = TestContext::new().await;
let raw = include_bytes!("../test-data/message/text_alt_plain.eml");
let parser = HtmlMsgParser::from_bytes(&t.ctx, raw).await.unwrap();
assert_eq!(
parser.html,
r##"
mime-modified should not be set set as there is no html and no special stuff;
although not being a delta-message.
test some special html-characters as < > and & but also " and ' :)
"##
);
}
#[async_std::test]
async fn test_htmlparse_html() {
let t = TestContext::new().await;
let raw = include_bytes!("../test-data/message/text_html.eml");
let parser = HtmlMsgParser::from_bytes(&t.ctx, raw).await.unwrap();
// on windows, `\r\n` linends are returned from mimeparser,
// however, rust multiline-strings use just `\n`;
// therefore, we just remove `\r` before comparison.
assert_eq!(
parser.html.replace("\r", ""),
r##"
mime-modified set; simplify is always regarded as lossy.
"##
);
}
#[async_std::test]
async fn test_htmlparse_alt_html() {
let t = TestContext::new().await;
let raw = include_bytes!("../test-data/message/text_alt_html.eml");
let parser = HtmlMsgParser::from_bytes(&t.ctx, raw).await.unwrap();
assert_eq!(
parser.html.replace("\r", ""), // see comment in test_htmlparse_html()
r##"
mime-modified set; simplify is always regarded as lossy.
"##
);
}
#[async_std::test]
async fn test_htmlparse_alt_plain_html() {
let t = TestContext::new().await;
let raw = include_bytes!("../test-data/message/text_alt_plain_html.eml");
let parser = HtmlMsgParser::from_bytes(&t.ctx, raw).await.unwrap();
assert_eq!(
parser.html.replace("\r", ""), // see comment in test_htmlparse_html()
r##"
this is html
"##
);
}
#[async_std::test]
async fn test_htmlparse_apple_cid_jpg() {
// load raw mime html-data with related image-part (cid:)
// and make sure, Content-Id has angle-brackets that are removed correctly.
let t = TestContext::new().await;
let raw = include_bytes!("../test-data/message/apple_cid_jpg.eml");
let test = String::from_utf8_lossy(raw);
assert!(test
.find("Content-Id: <8AE052EF-BC90-486F-BB78-58D3590308EC@fritz.box>")
.is_some());
assert!(test
.find("cid:8AE052EF-BC90-486F-BB78-58D3590308EC@fritz.box")
.is_some());
assert!(test.find("data:").is_none());
// parsing converts cid: to data:
let parser = HtmlMsgParser::from_bytes(&t.ctx, raw).await.unwrap();
assert!(parser.html.find("").is_some());
assert!(parser.html.find("Content-Id:").is_none());
assert!(parser
.html
.find("data:image/jpeg;base64,/9j/4AAQ")
.is_some());
assert!(parser.html.find("cid:").is_none());
}
}