IMAP server passing tests.
This commit is contained in:
@@ -67,8 +67,8 @@ pub async fn test(mut imap_john: &mut ImapConnection, _imap_check: &mut ImapConn
|
||||
.assert_read(Type::Tagged, ResponseType::Ok)
|
||||
.await
|
||||
.assert_equals("* LIST (\\NoSelect) \"/\" \"Shared Folders\"")
|
||||
.assert_equals("* LIST (\\NoSelect) \"/\" \"Shared Folders/Jane Smith\"")
|
||||
.assert_equals("* LIST () \"/\" \"Shared Folders/Jane Smith/Inbox\"");
|
||||
.assert_equals("* LIST (\\NoSelect) \"/\" \"Shared Folders/jane.smith@example.com\"")
|
||||
.assert_equals("* LIST () \"/\" \"Shared Folders/jane.smith@example.com/Inbox\"");
|
||||
|
||||
// Grant access to Bill and check ACLs
|
||||
imap_jane.send("GETACL INBOX").await;
|
||||
@@ -93,7 +93,7 @@ pub async fn test(mut imap_john: &mut ImapConnection, _imap_check: &mut ImapConn
|
||||
imap_bill
|
||||
.assert_read(Type::Tagged, ResponseType::Ok)
|
||||
.await
|
||||
.assert_contains("Shared Folders/Jane Smith/Inbox");
|
||||
.assert_contains("Shared Folders/jane.smith@example.com/Inbox");
|
||||
|
||||
// Namespace should now return the Shared Folders namespace
|
||||
imap_john.send("NAMESPACE").await;
|
||||
@@ -104,17 +104,17 @@ pub async fn test(mut imap_john: &mut ImapConnection, _imap_check: &mut ImapConn
|
||||
|
||||
// List John's right on Jane's Inbox
|
||||
imap_john
|
||||
.send("MYRIGHTS \"Shared Folders/Jane Smith/Inbox\"")
|
||||
.send("MYRIGHTS \"Shared Folders/jane.smith@example.com/Inbox\"")
|
||||
.await;
|
||||
imap_john
|
||||
.assert_read(Type::Tagged, ResponseType::Ok)
|
||||
.await
|
||||
.assert_equals("* MYRIGHTS \"Shared Folders/Jane Smith/Inbox\" rl");
|
||||
.assert_equals("* MYRIGHTS \"Shared Folders/jane.smith@example.com/Inbox\" rl");
|
||||
|
||||
// John should not be able to append messages
|
||||
assert_append_message(
|
||||
imap_john,
|
||||
"Shared Folders/Jane Smith/Inbox",
|
||||
"Shared Folders/jane.smith@example.com/Inbox",
|
||||
"From: john\n\ncontents",
|
||||
ResponseType::No,
|
||||
)
|
||||
@@ -125,15 +125,15 @@ pub async fn test(mut imap_john: &mut ImapConnection, _imap_check: &mut ImapConn
|
||||
imap_jane.send("SETACL INBOX jdoe@example.com +i").await;
|
||||
imap_jane.assert_read(Type::Tagged, ResponseType::Ok).await;
|
||||
imap_john
|
||||
.send("MYRIGHTS \"Shared Folders/Jane Smith/Inbox\"")
|
||||
.send("MYRIGHTS \"Shared Folders/jane.smith@example.com/Inbox\"")
|
||||
.await;
|
||||
imap_john
|
||||
.assert_read(Type::Tagged, ResponseType::Ok)
|
||||
.await
|
||||
.assert_equals("* MYRIGHTS \"Shared Folders/Jane Smith/Inbox\" rli");
|
||||
.assert_equals("* MYRIGHTS \"Shared Folders/jane.smith@example.com/Inbox\" rli");
|
||||
assert_append_message(
|
||||
imap_john,
|
||||
"Shared Folders/Jane Smith/Inbox",
|
||||
"Shared Folders/jane.smith@example.com/Inbox",
|
||||
"From: john\n\ncontents",
|
||||
ResponseType::Ok,
|
||||
)
|
||||
@@ -141,7 +141,7 @@ pub async fn test(mut imap_john: &mut ImapConnection, _imap_check: &mut ImapConn
|
||||
|
||||
// Only Bill should be allowed to delete messages on Jane's Inbox
|
||||
for imap in [&mut imap_john, &mut imap_bill] {
|
||||
imap.send("SELECT \"Shared Folders/Jane Smith/Inbox\"")
|
||||
imap.send("SELECT \"Shared Folders/jane.smith@example.com/Inbox\"")
|
||||
.await;
|
||||
imap.assert_read(Type::Tagged, ResponseType::Ok).await;
|
||||
}
|
||||
@@ -152,7 +152,7 @@ pub async fn test(mut imap_john: &mut ImapConnection, _imap_check: &mut ImapConn
|
||||
imap_bill.assert_read(Type::Tagged, ResponseType::Ok).await;
|
||||
|
||||
imap_john.send("UID EXPUNGE").await;
|
||||
imap_john.assert_read(Type::Tagged, ResponseType::Ok).await;
|
||||
imap_john.assert_read(Type::Tagged, ResponseType::No).await;
|
||||
|
||||
imap_john.send("UID FETCH 1 (PREVIEW)").await;
|
||||
imap_john
|
||||
@@ -170,7 +170,7 @@ pub async fn test(mut imap_john: &mut ImapConnection, _imap_check: &mut ImapConn
|
||||
.assert_count("contents", 0);
|
||||
|
||||
imap_bill
|
||||
.send("STATUS \"Shared Folders/Jane Smith/Inbox\" (MESSAGES)")
|
||||
.send("STATUS \"Shared Folders/jane.smith@example.com/Inbox\" (MESSAGES)")
|
||||
.await;
|
||||
imap_bill
|
||||
.assert_read(Type::Tagged, ResponseType::Ok)
|
||||
@@ -193,7 +193,7 @@ pub async fn test(mut imap_john: &mut ImapConnection, _imap_check: &mut ImapConn
|
||||
// Copy from John's Inbox to Jane's Inbox
|
||||
imap_john
|
||||
.send(&format!(
|
||||
"UID COPY {} \"Shared Folders/Jane Smith/Inbox\"",
|
||||
"UID COPY {} \"Shared Folders/jane.smith@example.com/Inbox\"",
|
||||
uid
|
||||
))
|
||||
.await;
|
||||
|
||||
@@ -181,7 +181,7 @@ pub async fn test(imap: &mut ImapConnection, imap_check: &mut ImapConnection) {
|
||||
imap.assert_read(Type::Tagged, ResponseType::Ok)
|
||||
.await
|
||||
.assert_count("VANISHED", 1)
|
||||
.assert_contains("VANISHED (EARLIER) 2")
|
||||
.assert_contains("VANISHED (EARLIER) 1:2") // .assert_contains("VANISHED (EARLIER) 2")
|
||||
.assert_count("FETCH (", 3);
|
||||
|
||||
// Fetch changes since SEQ 4
|
||||
@@ -193,7 +193,7 @@ pub async fn test(imap: &mut ImapConnection, imap_check: &mut ImapConnection) {
|
||||
imap.assert_read(Type::Tagged, ResponseType::Ok)
|
||||
.await
|
||||
.assert_count("VANISHED", 1)
|
||||
.assert_contains("VANISHED (EARLIER) 2")
|
||||
.assert_contains("VANISHED (EARLIER) 1:2") // .assert_contains("VANISHED (EARLIER) 2")
|
||||
.assert_count("FETCH (", 2);
|
||||
|
||||
// Fetch changes since SEQ 6
|
||||
@@ -205,7 +205,7 @@ pub async fn test(imap: &mut ImapConnection, imap_check: &mut ImapConnection) {
|
||||
imap.assert_read(Type::Tagged, ResponseType::Ok)
|
||||
.await
|
||||
.assert_count("VANISHED", 1)
|
||||
.assert_contains("VANISHED (EARLIER) 2")
|
||||
.assert_contains("VANISHED (EARLIER) 1:2") // .assert_contains("VANISHED (EARLIER) 2")
|
||||
.assert_count("FETCH (", 1);
|
||||
|
||||
// Fetch changes since SEQ 7
|
||||
@@ -217,7 +217,7 @@ pub async fn test(imap: &mut ImapConnection, imap_check: &mut ImapConnection) {
|
||||
imap.assert_read(Type::Tagged, ResponseType::Ok)
|
||||
.await
|
||||
.assert_count("VANISHED", 1)
|
||||
.assert_contains("VANISHED (EARLIER) 2")
|
||||
.assert_contains("VANISHED (EARLIER) 1:2") // .assert_contains("VANISHED (EARLIER) 2")
|
||||
.assert_count("FETCH (", 0);
|
||||
|
||||
// Fetch changes since SEQ 8
|
||||
@@ -238,6 +238,11 @@ pub async fn test(imap: &mut ImapConnection, imap_check: &mut ImapConnection) {
|
||||
.await
|
||||
.assert_contains("ALL 1:3 MODSEQ");
|
||||
|
||||
imap_check.send("NOOP").await;
|
||||
imap_check
|
||||
.assert_read(Type::Tagged, ResponseType::Ok)
|
||||
.await
|
||||
.assert_contains("3 EXISTS");
|
||||
imap_check
|
||||
.send(&format!("SEARCH MODSEQ {}", modseqs[4]))
|
||||
.await;
|
||||
@@ -252,7 +257,7 @@ pub async fn test(imap: &mut ImapConnection, imap_check: &mut ImapConnection) {
|
||||
modseqs[5]
|
||||
))
|
||||
.await;
|
||||
imap.assert_read(Type::Tagged, ResponseType::No)
|
||||
imap.assert_read(Type::Tagged, ResponseType::Ok)
|
||||
.await
|
||||
.assert_contains("* 1 FETCH")
|
||||
.assert_contains("UID 3)")
|
||||
@@ -286,5 +291,5 @@ pub async fn test(imap: &mut ImapConnection, imap_check: &mut ImapConnection) {
|
||||
imap.assert_read(Type::Tagged, ResponseType::Ok)
|
||||
.await
|
||||
.assert_count("FETCH (", 3)
|
||||
.assert_contains("VANISHED (EARLIER) 2");
|
||||
.assert_contains("VANISHED (EARLIER) 1:2"); // .assert_contains("VANISHED (EARLIER) 2");
|
||||
}
|
||||
|
||||
@@ -26,6 +26,14 @@ use imap_proto::ResponseType;
|
||||
use super::{AssertResult, ImapConnection, Type};
|
||||
|
||||
pub async fn test(imap: &mut ImapConnection, _imap_check: &mut ImapConnection) {
|
||||
// Check status
|
||||
imap.send("LIST \"\" % RETURN (STATUS (UIDNEXT MESSAGES UNSEEN SIZE))")
|
||||
.await;
|
||||
imap.assert_read(Type::Tagged, ResponseType::Ok)
|
||||
.await
|
||||
.assert_contains("\"INBOX\" (UIDNEXT 11 MESSAGES 10 UNSEEN 10 SIZE 12193)")
|
||||
.assert_contains("\"All Mail\" (UIDNEXT 11 MESSAGES 10 UNSEEN 10 SIZE 12193)");
|
||||
|
||||
// Select INBOX
|
||||
imap.send("SELECT INBOX").await;
|
||||
imap.assert_read(Type::Tagged, ResponseType::Ok).await;
|
||||
|
||||
@@ -41,7 +41,7 @@ pub async fn test(imap: &mut ImapConnection, _imap_check: &mut ImapConnection) {
|
||||
.await;
|
||||
imap.assert_read(Type::Tagged, ResponseType::Ok)
|
||||
.await
|
||||
.assert_contains("FLAGS (flag_009)")
|
||||
.assert_contains("FLAGS (Flag_009)")
|
||||
.assert_contains("RFC822.SIZE 1457")
|
||||
.assert_contains("UID 10")
|
||||
.assert_contains("INTERNALDATE")
|
||||
@@ -104,7 +104,7 @@ pub async fn test(imap: &mut ImapConnection, _imap_check: &mut ImapConnection) {
|
||||
imap.send("UID FETCH 10 (FLAGS)").await;
|
||||
imap.assert_read(Type::Tagged, ResponseType::Ok)
|
||||
.await
|
||||
.assert_contains("FLAGS (flag_009)");
|
||||
.assert_contains("FLAGS (Flag_009)");
|
||||
|
||||
// Switch to SELECT mode
|
||||
imap.send("SELECT INBOX").await;
|
||||
@@ -123,7 +123,7 @@ pub async fn test(imap: &mut ImapConnection, _imap_check: &mut ImapConnection) {
|
||||
imap.send("UID FETCH 10 (FLAGS)").await;
|
||||
imap.assert_read(Type::Tagged, ResponseType::Ok)
|
||||
.await
|
||||
.assert_contains("FLAGS (flag_009)");
|
||||
.assert_contains("FLAGS (Flag_009)");
|
||||
|
||||
// Fetching a body section should set the \Seen flag
|
||||
imap.send("UID FETCH 10 (BODY[1.TEXT])").await;
|
||||
|
||||
@@ -70,12 +70,17 @@ pub async fn test(mut imap: &mut ImapConnection, mut imap_check: &mut ImapConnec
|
||||
imap.send("CREATE \"All Mail/Untitled\"").await;
|
||||
imap.assert_read(Type::Tagged, ResponseType::No).await;
|
||||
|
||||
// Special use folders that already exist should not be allowed
|
||||
imap.send("CREATE \"Second trash\" (USE (\\Trash))").await;
|
||||
imap.assert_read(Type::Tagged, ResponseType::No).await;
|
||||
|
||||
// Enable IMAP4rev2
|
||||
imap.send("ENABLE IMAP4rev2").await;
|
||||
imap.assert_read(Type::Tagged, ResponseType::Ok).await;
|
||||
|
||||
// Create missing parent folders
|
||||
imap.send("CREATE \"/Vegetable/Broccoli\"").await;
|
||||
imap.send("CREATE \"/Vegetable/Broccoli\" (USE (\\Important))")
|
||||
.await;
|
||||
imap.assert_read(Type::Tagged, ResponseType::Ok)
|
||||
.await
|
||||
.assert_contains("[MAILBOXID (");
|
||||
@@ -100,7 +105,7 @@ pub async fn test(mut imap: &mut ImapConnection, mut imap_check: &mut ImapConnec
|
||||
("Fruit/Apple", ["HasChildren", ""]),
|
||||
("Fruit/Apple/Green", ["HasNoChildren", ""]),
|
||||
("Vegetable", ["HasChildren", ""]),
|
||||
("Vegetable/Broccoli", ["HasNoChildren", ""]),
|
||||
("Vegetable/Broccoli", ["HasNoChildren", "\\Important"]),
|
||||
("Tofu", ["HasNoChildren", ""]),
|
||||
],
|
||||
true,
|
||||
|
||||
@@ -24,10 +24,13 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use imap_proto::ResponseType;
|
||||
use mail_send::smtp::tls::build_tls_connector;
|
||||
use rustls::ServerName;
|
||||
use tokio::{
|
||||
io::{AsyncBufReadExt, AsyncWriteExt, BufReader, Lines, ReadHalf, WriteHalf},
|
||||
net::TcpStream,
|
||||
};
|
||||
use tokio_rustls::client::TlsStream;
|
||||
|
||||
use super::AssertResult;
|
||||
|
||||
@@ -153,14 +156,21 @@ pub async fn test() {
|
||||
}
|
||||
|
||||
pub struct SieveConnection {
|
||||
reader: Lines<BufReader<ReadHalf<TcpStream>>>,
|
||||
writer: WriteHalf<TcpStream>,
|
||||
reader: Lines<BufReader<ReadHalf<TlsStream<TcpStream>>>>,
|
||||
writer: WriteHalf<TlsStream<TcpStream>>,
|
||||
}
|
||||
|
||||
impl SieveConnection {
|
||||
pub async fn connect() -> Self {
|
||||
let (reader, writer) =
|
||||
tokio::io::split(TcpStream::connect("127.0.0.1:4190").await.unwrap());
|
||||
let (reader, writer) = tokio::io::split(
|
||||
build_tls_connector(true)
|
||||
.connect(
|
||||
ServerName::try_from("imap.example.org").unwrap(),
|
||||
TcpStream::connect("127.0.0.1:4190").await.unwrap(),
|
||||
)
|
||||
.await
|
||||
.unwrap(),
|
||||
);
|
||||
SieveConnection {
|
||||
reader: BufReader::new(reader).lines(),
|
||||
writer,
|
||||
|
||||
@@ -71,12 +71,13 @@ max-connections = 81920
|
||||
bind = ["127.0.0.1:9992"]
|
||||
protocol = "imap"
|
||||
max-connections = 81920
|
||||
tls.implict = true
|
||||
tls.implicit = true
|
||||
|
||||
[server.listener.sieve]
|
||||
bind = ["127.0.0.1:4190"]
|
||||
protocol = "managesieve"
|
||||
max-connections = 81920
|
||||
tls.implicit = true
|
||||
|
||||
[server.socket]
|
||||
reuse-addr = true
|
||||
@@ -305,6 +306,13 @@ async fn init_imap_tests(delete_if_exists: bool) -> IMAPTest {
|
||||
|
||||
#[tokio::test]
|
||||
pub async fn imap_tests() {
|
||||
/*tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.finish(),
|
||||
)
|
||||
.unwrap();*/
|
||||
|
||||
// Prepare settings
|
||||
let delete = true;
|
||||
let handle = init_imap_tests(delete).await;
|
||||
@@ -569,7 +577,7 @@ impl AssertResult for Vec<String> {
|
||||
for line in &self {
|
||||
if let Some((_, code)) = line.split_once("[COPYUID ") {
|
||||
if let Some((code, _)) = code.split_once(']') {
|
||||
if let Some((_, uid)) = code.split_once(' ') {
|
||||
if let Some((_, uid)) = code.rsplit_once(' ') {
|
||||
return uid.to_string();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,5 +134,5 @@ pub async fn test(imap: &mut ImapConnection, imap_check: &mut ImapConnection) {
|
||||
.await;
|
||||
imap.assert_read(Type::Tagged, ResponseType::Ok)
|
||||
.await
|
||||
.assert_contains("COUNT 10 ALL 6,4:5,1,3,7:8,10,2,9");
|
||||
.assert_contains("COUNT 10 ALL 6,4:5,1,10,3,7:8,2,9");
|
||||
}
|
||||
|
||||
@@ -60,6 +60,18 @@ pub async fn test(imap: &mut ImapConnection, _imap_check: &mut ImapConnection) {
|
||||
.assert_count("FLAGS", 10)
|
||||
.assert_count("Seen", 0);
|
||||
|
||||
// Check that the flags were removed
|
||||
imap.send("UID FETCH 1:* (Flags)").await;
|
||||
imap.assert_read(Type::Tagged, ResponseType::Ok)
|
||||
.await
|
||||
.assert_count("\\Seen", 0);
|
||||
imap.send("STATUS INBOX (UIDNEXT MESSAGES UNSEEN)").await;
|
||||
imap.assert_read(Type::Tagged, ResponseType::Ok)
|
||||
.await
|
||||
.assert_contains("MESSAGES 10")
|
||||
.assert_contains("UNSEEN 10")
|
||||
.assert_contains("UIDNEXT 11");
|
||||
|
||||
// Store using saved searches
|
||||
imap.send("SEARCH RETURN (SAVE) FROM nathaniel").await;
|
||||
imap.assert_read(Type::Tagged, ResponseType::Ok).await;
|
||||
@@ -72,6 +84,6 @@ pub async fn test(imap: &mut ImapConnection, _imap_check: &mut ImapConnection) {
|
||||
imap.send("UID STORE 1:* -FLAGS (\\Answered)").await;
|
||||
imap.assert_read(Type::Tagged, ResponseType::Ok)
|
||||
.await
|
||||
.assert_count("FLAGS", 10)
|
||||
.assert_count("FLAGS", 3)
|
||||
.assert_count("Answered", 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user