Support for external email addresses on mailing lists (closes #152)
This commit is contained in:
@@ -6,10 +6,13 @@
|
||||
|
||||
use ahash::AHashSet;
|
||||
use directory::{
|
||||
backend::internal::{
|
||||
lookup::DirectoryStore,
|
||||
manage::{self, ManageDirectory, UpdatePrincipal},
|
||||
PrincipalField, PrincipalUpdate, PrincipalValue,
|
||||
backend::{
|
||||
internal::{
|
||||
lookup::DirectoryStore,
|
||||
manage::{self, ManageDirectory, UpdatePrincipal},
|
||||
PrincipalField, PrincipalUpdate, PrincipalValue,
|
||||
},
|
||||
RcptType,
|
||||
},
|
||||
Principal, QueryBy, Type,
|
||||
};
|
||||
@@ -117,10 +120,13 @@ async fn internal_directory() {
|
||||
.await,
|
||||
Ok(())
|
||||
);
|
||||
assert!(store.rcpt("john@example.org").await.unwrap());
|
||||
assert_eq!(
|
||||
store.email_to_ids("john@example.org").await.unwrap(),
|
||||
vec![john_id]
|
||||
store.rcpt("john@example.org").await.unwrap(),
|
||||
RcptType::Mailbox
|
||||
);
|
||||
assert_eq!(
|
||||
store.email_to_id("john@example.org").await.unwrap(),
|
||||
Some(john_id)
|
||||
);
|
||||
|
||||
// Using non-existent domain should fail
|
||||
@@ -154,11 +160,17 @@ async fn internal_directory() {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert!(store.rcpt("jane@example.org").await.unwrap());
|
||||
assert!(!store.rcpt("jane@otherdomain.org").await.unwrap());
|
||||
assert_eq!(
|
||||
store.email_to_ids("jane@example.org").await.unwrap(),
|
||||
vec![jane_id]
|
||||
store.rcpt("jane@example.org").await.unwrap(),
|
||||
RcptType::Mailbox
|
||||
);
|
||||
assert_eq!(
|
||||
store.rcpt("jane@otherdomain.org").await.unwrap(),
|
||||
RcptType::Invalid
|
||||
);
|
||||
assert_eq!(
|
||||
store.email_to_id("jane@example.org").await.unwrap(),
|
||||
Some(jane_id)
|
||||
);
|
||||
assert_eq!(store.vrfy("jane").await.unwrap(), vec!["jane@example.org"]);
|
||||
assert_eq!(
|
||||
@@ -239,21 +251,31 @@ async fn internal_directory() {
|
||||
PrincipalUpdate::set(
|
||||
PrincipalField::Members,
|
||||
PrincipalValue::StringList(vec!["john".to_string(), "jane".to_string()]),
|
||||
),
|
||||
PrincipalUpdate::set(
|
||||
PrincipalField::ExternalMembers,
|
||||
PrincipalValue::StringList(vec![
|
||||
"mike@other.org".to_string(),
|
||||
"lucy@foobar.net".to_string()
|
||||
]),
|
||||
)
|
||||
]))
|
||||
.await,
|
||||
Ok(())
|
||||
);
|
||||
assert!(store.rcpt("list@example.org").await.unwrap());
|
||||
assert_eq!(
|
||||
store
|
||||
.email_to_ids("list@example.org")
|
||||
.await
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.collect::<AHashSet<_>>(),
|
||||
[john_id, jane_id].into_iter().collect::<AHashSet<_>>(),
|
||||
);
|
||||
|
||||
assert_list_members(
|
||||
&store,
|
||||
"list@example.org",
|
||||
[
|
||||
"john@example.org",
|
||||
"mike@other.org",
|
||||
"lucy@foobar.net",
|
||||
"jane@example.org",
|
||||
],
|
||||
)
|
||||
.await;
|
||||
|
||||
assert_eq!(
|
||||
store
|
||||
.query(QueryBy::Name("list"), true)
|
||||
@@ -276,10 +298,15 @@ async fn internal_directory() {
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.collect::<AHashSet<_>>(),
|
||||
["john@example.org", "jane@example.org"]
|
||||
.into_iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect::<AHashSet<_>>()
|
||||
[
|
||||
"john@example.org",
|
||||
"mike@other.org",
|
||||
"lucy@foobar.net",
|
||||
"jane@example.org"
|
||||
]
|
||||
.into_iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect::<AHashSet<_>>()
|
||||
);
|
||||
|
||||
// Create groups
|
||||
@@ -445,8 +472,14 @@ async fn internal_directory() {
|
||||
}
|
||||
);
|
||||
assert_eq!(store.get_principal_id("john").await.unwrap(), None);
|
||||
assert!(!store.rcpt("john@example.org").await.unwrap());
|
||||
assert!(store.rcpt("john.doe@example.org").await.unwrap());
|
||||
assert_eq!(
|
||||
store.rcpt("john@example.org").await.unwrap(),
|
||||
RcptType::Invalid
|
||||
);
|
||||
assert_eq!(
|
||||
store.rcpt("john.doe@example.org").await.unwrap(),
|
||||
RcptType::Mailbox
|
||||
);
|
||||
|
||||
// Remove a member from a mailing list and then add it back
|
||||
assert_eq!(
|
||||
@@ -460,10 +493,12 @@ async fn internal_directory() {
|
||||
.await,
|
||||
Ok(())
|
||||
);
|
||||
assert_eq!(
|
||||
store.email_to_ids("list@example.org").await.unwrap(),
|
||||
vec![jane_id]
|
||||
);
|
||||
assert_list_members(
|
||||
&store,
|
||||
"list@example.org",
|
||||
["jane@example.org", "mike@other.org", "lucy@foobar.net"],
|
||||
)
|
||||
.await;
|
||||
assert_eq!(
|
||||
store
|
||||
.update_principal(UpdatePrincipal::by_name("list").with_updates(vec![
|
||||
@@ -475,15 +510,17 @@ async fn internal_directory() {
|
||||
.await,
|
||||
Ok(())
|
||||
);
|
||||
assert_eq!(
|
||||
store
|
||||
.email_to_ids("list@example.org")
|
||||
.await
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.collect::<AHashSet<_>>(),
|
||||
[john_id, jane_id].into_iter().collect::<AHashSet<_>>()
|
||||
);
|
||||
assert_list_members(
|
||||
&store,
|
||||
"list@example.org",
|
||||
[
|
||||
"john.doe@example.org",
|
||||
"jane@example.org",
|
||||
"mike@other.org",
|
||||
"lucy@foobar.net",
|
||||
],
|
||||
)
|
||||
.await;
|
||||
|
||||
// Field validation
|
||||
assert_eq!(
|
||||
@@ -619,10 +656,13 @@ async fn internal_directory() {
|
||||
store.delete_principal(QueryBy::Id(john_id)).await.unwrap();
|
||||
assert_eq!(store.get_principal_id("john.doe").await.unwrap(), None);
|
||||
assert_eq!(
|
||||
store.email_to_ids("john.doe@example.org").await.unwrap(),
|
||||
Vec::<u32>::new()
|
||||
store.email_to_id("john.doe@example.org").await.unwrap(),
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
store.rcpt("john.doe@example.org").await.unwrap(),
|
||||
RcptType::Invalid
|
||||
);
|
||||
assert!(!store.rcpt("john.doe@example.org").await.unwrap());
|
||||
assert_eq!(
|
||||
store
|
||||
.list_principals(
|
||||
@@ -672,10 +712,13 @@ async fn internal_directory() {
|
||||
// Make sure Jane's records are still there
|
||||
assert_eq!(store.get_principal_id("jane").await.unwrap(), Some(jane_id));
|
||||
assert_eq!(
|
||||
store.email_to_ids("jane@example.org").await.unwrap(),
|
||||
vec![jane_id]
|
||||
store.email_to_id("jane@example.org").await.unwrap(),
|
||||
Some(jane_id)
|
||||
);
|
||||
assert_eq!(
|
||||
store.rcpt("jane@example.org").await.unwrap(),
|
||||
RcptType::Mailbox
|
||||
);
|
||||
assert!(store.rcpt("jane@example.org").await.unwrap());
|
||||
assert_eq!(
|
||||
store
|
||||
.get_bitmap(BitmapKey {
|
||||
@@ -885,3 +928,22 @@ impl TestInternalDirectory for Store {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn assert_list_members(
|
||||
store: &Store,
|
||||
list_addr: &str,
|
||||
members: impl IntoIterator<Item = &str>,
|
||||
) {
|
||||
match store.rcpt(list_addr).await.unwrap() {
|
||||
RcptType::List(items) => {
|
||||
assert_eq!(
|
||||
items.into_iter().collect::<AHashSet<_>>(),
|
||||
members
|
||||
.into_iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect::<AHashSet<_>>()
|
||||
);
|
||||
}
|
||||
other => panic!("invalid {other:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,15 @@
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
use directory::{backend::internal::manage::ManageDirectory, QueryBy, Type, ROLE_USER};
|
||||
use directory::{
|
||||
backend::{internal::manage::ManageDirectory, RcptType},
|
||||
QueryBy, Type, ROLE_USER,
|
||||
};
|
||||
use mail_send::Credentials;
|
||||
|
||||
use crate::directory::{map_account_ids, DirectoryTest, IntoTestPrincipal, TestPrincipal};
|
||||
use crate::directory::{
|
||||
map_account_id, map_account_ids, DirectoryTest, IntoTestPrincipal, TestPrincipal,
|
||||
};
|
||||
|
||||
#[tokio::test]
|
||||
async fn ldap_directory() {
|
||||
@@ -149,41 +154,29 @@ async fn ldap_directory() {
|
||||
);
|
||||
|
||||
// Ids by email
|
||||
compare_sorted(
|
||||
core.email_to_ids(&handle, "jane@example.org", 0)
|
||||
assert_eq!(
|
||||
core.email_to_id(&handle, "jane@example.org", 0)
|
||||
.await
|
||||
.unwrap(),
|
||||
map_account_ids(base_store, vec!["jane"]).await,
|
||||
);
|
||||
compare_sorted(
|
||||
core.email_to_ids(&handle, "jane+alias@example.org", 0)
|
||||
.await
|
||||
.unwrap(),
|
||||
map_account_ids(base_store, vec!["jane"]).await,
|
||||
);
|
||||
compare_sorted(
|
||||
core.email_to_ids(&handle, "info@example.org", 0)
|
||||
.await
|
||||
.unwrap(),
|
||||
map_account_ids(base_store, vec!["bill", "jane", "john"]).await,
|
||||
);
|
||||
compare_sorted(
|
||||
core.email_to_ids(&handle, "info+alias@example.org", 0)
|
||||
.await
|
||||
.unwrap(),
|
||||
map_account_ids(base_store, vec!["bill", "jane", "john"]).await,
|
||||
);
|
||||
compare_sorted(
|
||||
core.email_to_ids(&handle, "unknown@example.org", 0)
|
||||
.await
|
||||
.unwrap(),
|
||||
Vec::<u32>::new(),
|
||||
Some(map_account_id(base_store, "jane").await),
|
||||
);
|
||||
assert_eq!(
|
||||
core.email_to_ids(&handle, "anything@catchall.org", 0)
|
||||
core.email_to_id(&handle, "jane+alias@example.org", 0)
|
||||
.await
|
||||
.unwrap(),
|
||||
map_account_ids(base_store, vec!["robert"]).await
|
||||
Some(map_account_id(base_store, "jane").await),
|
||||
);
|
||||
assert_eq!(
|
||||
core.email_to_id(&handle, "unknown@example.org", 0)
|
||||
.await
|
||||
.unwrap(),
|
||||
None,
|
||||
);
|
||||
assert_eq!(
|
||||
core.email_to_id(&handle, "anything@catchall.org", 0)
|
||||
.await
|
||||
.unwrap(),
|
||||
Some(map_account_id(base_store, "robert").await)
|
||||
);
|
||||
|
||||
// Domain validation
|
||||
@@ -191,21 +184,36 @@ async fn ldap_directory() {
|
||||
assert!(!handle.is_local_domain("other.org").await.unwrap());
|
||||
|
||||
// RCPT TO
|
||||
assert!(core.rcpt(&handle, "jane@example.org", 0).await.unwrap());
|
||||
assert!(core.rcpt(&handle, "info@example.org", 0).await.unwrap());
|
||||
assert!(core
|
||||
.rcpt(&handle, "jane+alias@example.org", 0)
|
||||
.await
|
||||
.unwrap());
|
||||
assert!(core
|
||||
.rcpt(&handle, "info+alias@example.org", 0)
|
||||
.await
|
||||
.unwrap());
|
||||
assert!(core
|
||||
.rcpt(&handle, "random_user@catchall.org", 0)
|
||||
.await
|
||||
.unwrap());
|
||||
assert!(!core.rcpt(&handle, "invalid@example.org", 0).await.unwrap());
|
||||
assert_eq!(
|
||||
core.rcpt(&handle, "jane@example.org", 0).await.unwrap(),
|
||||
RcptType::Mailbox
|
||||
);
|
||||
assert_eq!(
|
||||
core.rcpt(&handle, "info@example.org", 0).await.unwrap(),
|
||||
RcptType::Mailbox
|
||||
);
|
||||
assert_eq!(
|
||||
core.rcpt(&handle, "jane+alias@example.org", 0)
|
||||
.await
|
||||
.unwrap(),
|
||||
RcptType::Mailbox
|
||||
);
|
||||
assert_eq!(
|
||||
core.rcpt(&handle, "info+alias@example.org", 0)
|
||||
.await
|
||||
.unwrap(),
|
||||
RcptType::Mailbox
|
||||
);
|
||||
assert_eq!(
|
||||
core.rcpt(&handle, "random_user@catchall.org", 0)
|
||||
.await
|
||||
.unwrap(),
|
||||
RcptType::Mailbox
|
||||
);
|
||||
assert_eq!(
|
||||
core.rcpt(&handle, "invalid@example.org", 0).await.unwrap(),
|
||||
RcptType::Invalid
|
||||
);
|
||||
|
||||
// VRFY
|
||||
compare_sorted(
|
||||
@@ -214,7 +222,10 @@ async fn ldap_directory() {
|
||||
);
|
||||
compare_sorted(
|
||||
core.vrfy(&handle, "john", 0).await.unwrap(),
|
||||
vec!["john@example.org".to_string()],
|
||||
vec![
|
||||
"john@example.org".to_string(),
|
||||
"john.doe@example.org".to_string(),
|
||||
],
|
||||
);
|
||||
compare_sorted(
|
||||
core.vrfy(&handle, "jane+alias@example", 0).await.unwrap(),
|
||||
@@ -230,7 +241,8 @@ async fn ldap_directory() {
|
||||
);
|
||||
|
||||
// EXPN
|
||||
compare_sorted(
|
||||
// Now handled by the internal directory
|
||||
/*compare_sorted(
|
||||
core.expn(&handle, "info@example.org", 0).await.unwrap(),
|
||||
vec![
|
||||
"bill@example.org".to_string(),
|
||||
@@ -241,7 +253,7 @@ async fn ldap_directory() {
|
||||
compare_sorted(
|
||||
core.expn(&handle, "john@example.org", 0).await.unwrap(),
|
||||
Vec::<String>::new(),
|
||||
);
|
||||
);*/
|
||||
}
|
||||
|
||||
fn compare_sorted<T: Eq + Debug>(v1: Vec<T>, v2: Vec<T>) {
|
||||
|
||||
@@ -701,13 +701,15 @@ async fn address_mappings() {
|
||||
async fn map_account_ids(store: &Store, names: Vec<impl AsRef<str>>) -> Vec<u32> {
|
||||
let mut ids = Vec::with_capacity(names.len());
|
||||
for name in names {
|
||||
ids.push(
|
||||
store
|
||||
.get_principal_id(name.as_ref())
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap(),
|
||||
);
|
||||
ids.push(map_account_id(store, name).await);
|
||||
}
|
||||
ids
|
||||
}
|
||||
|
||||
async fn map_account_id(store: &Store, name: impl AsRef<str>) -> u32 {
|
||||
store
|
||||
.get_principal_id(name.as_ref())
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use common::listener::limiter::{ConcurrencyLimiter, InFlight};
|
||||
use directory::QueryBy;
|
||||
use directory::{backend::RcptType, QueryBy};
|
||||
use mail_parser::decoders::base64::base64_decode;
|
||||
use mail_send::Credentials;
|
||||
use tokio::{
|
||||
@@ -78,7 +78,9 @@ async fn lmtp_directory() {
|
||||
|
||||
for (item, expected) in &tests {
|
||||
let result: LookupResult = match item {
|
||||
Item::IsAccount(v) => core.rcpt(&handle, v, 0).await.unwrap().into(),
|
||||
Item::IsAccount(v) => {
|
||||
(core.rcpt(&handle, v, 0).await.unwrap() == RcptType::Mailbox).into()
|
||||
}
|
||||
Item::Authenticate(v) => handle
|
||||
.query(QueryBy::Credentials(v), true)
|
||||
.await
|
||||
@@ -122,7 +124,9 @@ async fn lmtp_directory() {
|
||||
requests.push((
|
||||
tokio::spawn(async move {
|
||||
let result: LookupResult = match &item {
|
||||
Item::IsAccount(v) => core.rcpt(&handle, v, 0).await.unwrap().into(),
|
||||
Item::IsAccount(v) => {
|
||||
(core.rcpt(&handle, v, 0).await.unwrap() == RcptType::Mailbox).into()
|
||||
}
|
||||
Item::Authenticate(v) => handle
|
||||
.query(QueryBy::Credentials(v), true)
|
||||
.await
|
||||
@@ -182,7 +186,9 @@ async fn lmtp_directory() {
|
||||
requests.push((
|
||||
tokio::spawn(async move {
|
||||
let result: LookupResult = match &item {
|
||||
Item::IsAccount(v) => core.rcpt(&handle, v, 0).await.unwrap().into(),
|
||||
Item::IsAccount(v) => {
|
||||
(core.rcpt(&handle, v, 0).await.unwrap() == RcptType::Mailbox).into()
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
|
||||
@@ -4,11 +4,18 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use directory::{backend::internal::manage::ManageDirectory, QueryBy, Type, ROLE_USER};
|
||||
use directory::{
|
||||
backend::{internal::manage::ManageDirectory, RcptType},
|
||||
QueryBy, Type, ROLE_USER,
|
||||
};
|
||||
use mail_send::Credentials;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use store::{LookupStore, Store};
|
||||
|
||||
use crate::directory::{map_account_ids, DirectoryTest, IntoTestPrincipal, TestPrincipal};
|
||||
use crate::directory::{
|
||||
map_account_id, map_account_ids, DirectoryTest, IntoTestPrincipal, TestPrincipal,
|
||||
};
|
||||
|
||||
use super::DirectoryStore;
|
||||
|
||||
@@ -243,40 +250,28 @@ async fn sql_directory() {
|
||||
|
||||
// Ids by email
|
||||
assert_eq!(
|
||||
core.email_to_ids(&handle, "jane@example.org", 0)
|
||||
core.email_to_id(&handle, "jane@example.org", 0)
|
||||
.await
|
||||
.unwrap(),
|
||||
map_account_ids(base_store, vec!["jane"]).await
|
||||
Some(map_account_id(base_store, "jane").await)
|
||||
);
|
||||
assert_eq!(
|
||||
core.email_to_ids(&handle, "info@example.org", 0)
|
||||
core.email_to_id(&handle, "jane+alias@example.org", 0)
|
||||
.await
|
||||
.unwrap(),
|
||||
map_account_ids(base_store, vec!["bill", "jane", "john"]).await
|
||||
Some(map_account_id(base_store, "jane").await)
|
||||
);
|
||||
assert_eq!(
|
||||
core.email_to_ids(&handle, "jane+alias@example.org", 0)
|
||||
core.email_to_id(&handle, "unknown@example.org", 0)
|
||||
.await
|
||||
.unwrap(),
|
||||
map_account_ids(base_store, vec!["jane"]).await
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
core.email_to_ids(&handle, "info+alias@example.org", 0)
|
||||
core.email_to_id(&handle, "anything@catchall.org", 0)
|
||||
.await
|
||||
.unwrap(),
|
||||
map_account_ids(base_store, vec!["bill", "jane", "john"]).await
|
||||
);
|
||||
assert_eq!(
|
||||
core.email_to_ids(&handle, "unknown@example.org", 0)
|
||||
.await
|
||||
.unwrap(),
|
||||
Vec::<u32>::new()
|
||||
);
|
||||
assert_eq!(
|
||||
core.email_to_ids(&handle, "anything@catchall.org", 0)
|
||||
.await
|
||||
.unwrap(),
|
||||
map_account_ids(base_store, vec!["robert"]).await
|
||||
Some(map_account_id(base_store, "robert").await)
|
||||
);
|
||||
|
||||
// Domain validation
|
||||
@@ -284,21 +279,36 @@ async fn sql_directory() {
|
||||
assert!(!handle.is_local_domain("other.org").await.unwrap());
|
||||
|
||||
// RCPT TO
|
||||
assert!(core.rcpt(&handle, "jane@example.org", 0).await.unwrap());
|
||||
assert!(core.rcpt(&handle, "info@example.org", 0).await.unwrap());
|
||||
assert!(core
|
||||
.rcpt(&handle, "jane+alias@example.org", 0)
|
||||
.await
|
||||
.unwrap());
|
||||
assert!(core
|
||||
.rcpt(&handle, "info+alias@example.org", 0)
|
||||
.await
|
||||
.unwrap());
|
||||
assert!(core
|
||||
.rcpt(&handle, "random_user@catchall.org", 0)
|
||||
.await
|
||||
.unwrap());
|
||||
assert!(!core.rcpt(&handle, "invalid@example.org", 0).await.unwrap());
|
||||
assert_eq!(
|
||||
core.rcpt(&handle, "jane@example.org", 0).await.unwrap(),
|
||||
RcptType::Mailbox
|
||||
);
|
||||
assert_eq!(
|
||||
core.rcpt(&handle, "info@example.org", 0).await.unwrap(),
|
||||
RcptType::Mailbox
|
||||
);
|
||||
assert_eq!(
|
||||
core.rcpt(&handle, "jane+alias@example.org", 0)
|
||||
.await
|
||||
.unwrap(),
|
||||
RcptType::Mailbox
|
||||
);
|
||||
assert_eq!(
|
||||
core.rcpt(&handle, "info+alias@example.org", 0)
|
||||
.await
|
||||
.unwrap(),
|
||||
RcptType::Mailbox
|
||||
);
|
||||
assert_eq!(
|
||||
core.rcpt(&handle, "random_user@catchall.org", 0)
|
||||
.await
|
||||
.unwrap(),
|
||||
RcptType::Mailbox
|
||||
);
|
||||
assert_eq!(
|
||||
core.rcpt(&handle, "invalid@example.org", 0).await.unwrap(),
|
||||
RcptType::Invalid
|
||||
);
|
||||
|
||||
// VRFY
|
||||
assert_eq!(
|
||||
@@ -307,7 +317,10 @@ async fn sql_directory() {
|
||||
);
|
||||
assert_eq!(
|
||||
core.vrfy(&handle, "john", 0).await.unwrap(),
|
||||
vec!["john@example.org".to_string()]
|
||||
vec![
|
||||
"john.doe@example.org".to_string(),
|
||||
"john@example.org".to_string(),
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
core.vrfy(&handle, "jane+alias@example", 0).await.unwrap(),
|
||||
@@ -322,8 +335,8 @@ async fn sql_directory() {
|
||||
Vec::<String>::new()
|
||||
);
|
||||
|
||||
// EXPN
|
||||
assert_eq!(
|
||||
// EXPN (now handled by the internal store)
|
||||
/*assert_eq!(
|
||||
core.expn(&handle, "info@example.org", 0).await.unwrap(),
|
||||
vec![
|
||||
"bill@example.org".to_string(),
|
||||
@@ -334,7 +347,7 @@ async fn sql_directory() {
|
||||
assert_eq!(
|
||||
core.expn(&handle, "john@example.org", 0).await.unwrap(),
|
||||
Vec::<String>::new()
|
||||
);
|
||||
);*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user