mirror of
https://github.com/stalwartlabs/stalwart.git
synced 2026-03-17 14:34:03 +00:00
JMAP tests cleanup
This commit is contained in:
@@ -16,6 +16,7 @@ use serde::{
|
||||
de::{self, IgnoredAny, Visitor},
|
||||
ser::SerializeMap,
|
||||
};
|
||||
use serde_json::Value;
|
||||
use std::{collections::hash_map::Entry, fmt, str::FromStr};
|
||||
use store::{
|
||||
U32_LEN, U64_LEN,
|
||||
@@ -1126,18 +1127,15 @@ impl<'de> serde::Deserialize<'de> for PrincipalSet {
|
||||
let mut principal = PrincipalSet::default();
|
||||
|
||||
while let Some(key) = map.next_key::<&str>()? {
|
||||
let key = PrincipalField::try_parse(key)
|
||||
.or_else(|| {
|
||||
if key == "id" {
|
||||
// Ignored
|
||||
Some(PrincipalField::UsedQuota)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.ok_or_else(|| {
|
||||
serde::de::Error::custom(format!("invalid principal field: {}", key))
|
||||
})?;
|
||||
if key == "id" {
|
||||
// Ignored
|
||||
map.next_value::<IgnoredAny>()?;
|
||||
continue;
|
||||
}
|
||||
|
||||
let key = PrincipalField::try_parse(key).ok_or_else(|| {
|
||||
serde::de::Error::custom(format!("invalid principal field: {}", key))
|
||||
})?;
|
||||
|
||||
let value = match key {
|
||||
PrincipalField::Name => {
|
||||
@@ -1179,18 +1177,37 @@ impl<'de> serde::Deserialize<'de> for PrincipalSet {
|
||||
| PrincipalField::EnabledPermissions
|
||||
| PrincipalField::DisabledPermissions
|
||||
| PrincipalField::Urls
|
||||
| PrincipalField::ExternalMembers => {
|
||||
match map.next_value::<StringOrMany>()? {
|
||||
StringOrMany::One(v) => PrincipalValue::StringList(vec![v]),
|
||||
StringOrMany::Many(v) => {
|
||||
if !v.is_empty() {
|
||||
PrincipalValue::StringList(v)
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
| PrincipalField::ExternalMembers => match map.next_value::<Value>()? {
|
||||
Value::String(v) => {
|
||||
if v.len() <= MAX_STRING_LEN {
|
||||
PrincipalValue::StringList(vec![v])
|
||||
} else {
|
||||
return Err(serde::de::Error::custom("string too long"));
|
||||
}
|
||||
}
|
||||
}
|
||||
Value::Array(v) => {
|
||||
if !v.is_empty() {
|
||||
PrincipalValue::StringList(
|
||||
v.into_iter()
|
||||
.filter_map(|item| {
|
||||
if let Value::String(s) = item {
|
||||
if s.len() <= MAX_STRING_LEN {
|
||||
Some(s)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
_ => continue,
|
||||
},
|
||||
PrincipalField::UsedQuota => {
|
||||
// consume and ignore
|
||||
map.next_value::<IgnoredAny>()?;
|
||||
@@ -1263,66 +1280,6 @@ impl<'de> serde::Deserialize<'de> for StringOrU64 {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum StringOrMany {
|
||||
One(String),
|
||||
Many(Vec<String>),
|
||||
}
|
||||
|
||||
impl<'de> serde::Deserialize<'de> for StringOrMany {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct StringOrManyVisitor;
|
||||
|
||||
impl<'de> Visitor<'de> for StringOrManyVisitor {
|
||||
type Value = StringOrMany;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("a string or a sequence of strings")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
if value.len() <= MAX_STRING_LEN {
|
||||
Ok(StringOrMany::One(value.into()))
|
||||
} else {
|
||||
Err(serde::de::Error::custom("string too long"))
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
if v.len() <= MAX_STRING_LEN {
|
||||
Ok(StringOrMany::One(v))
|
||||
} else {
|
||||
Err(serde::de::Error::custom("string too long"))
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: de::SeqAccess<'de>,
|
||||
{
|
||||
let mut vec = Vec::new();
|
||||
|
||||
while let Some(value) = seq.next_element::<String>()? {
|
||||
vec.push(value);
|
||||
}
|
||||
|
||||
Ok(StringOrMany::Many(vec))
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_any(StringOrManyVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl Permission {
|
||||
pub fn all() -> impl Iterator<Item = Permission> {
|
||||
(0..Permission::COUNT as u32).filter_map(Permission::from_id)
|
||||
|
||||
@@ -417,6 +417,7 @@ pub enum Permission {
|
||||
JmapParticipantIdentityGet,
|
||||
JmapParticipantIdentitySet,
|
||||
JmapParticipantIdentityChanges,
|
||||
// TODO: Reuse DeleteSystemFolders position for new permission
|
||||
// WARNING: add new ids at the end (TODO: use static ids)
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ use crate::{
|
||||
use common::{
|
||||
Server, auth::AccessToken, sharing::EffectiveAcl, storage::index::ObjectIndexBuilder,
|
||||
};
|
||||
use directory::Permission;
|
||||
use store::{roaring::RoaringBitmap, write::BatchBuilder};
|
||||
use trc::AddContext;
|
||||
use types::{acl::Acl, collection::Collection, field::MailboxField};
|
||||
@@ -45,17 +44,8 @@ impl MailboxDestroy for Server {
|
||||
remove_emails: bool,
|
||||
) -> trc::Result<Result<Option<u64>, MailboxDestroyError>> {
|
||||
// Internal folders cannot be deleted
|
||||
#[cfg(feature = "test_mode")]
|
||||
if [INBOX_ID, TRASH_ID].contains(&document_id)
|
||||
&& !access_token.has_permission(Permission::DeleteSystemFolders)
|
||||
{
|
||||
return Ok(Err(MailboxDestroyError::CannotDestroy));
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "test_mode"))]
|
||||
if [INBOX_ID, TRASH_ID, JUNK_ID].contains(&document_id)
|
||||
&& !access_token.has_permission(Permission::DeleteSystemFolders)
|
||||
{
|
||||
if [INBOX_ID, TRASH_ID, JUNK_ID].contains(&document_id) {
|
||||
return Ok(Err(MailboxDestroyError::CannotDestroy));
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,8 @@ use jmap_proto::{
|
||||
types::state::State,
|
||||
};
|
||||
use jmap_tools::{Map, Value};
|
||||
use std::future::Future;
|
||||
use std::{future::Future, sync::Arc};
|
||||
use trc::AddContext;
|
||||
use types::{id::Id, type_state::DataType};
|
||||
|
||||
pub trait QuotaGet: Sync + Send {
|
||||
@@ -59,6 +60,16 @@ impl QuotaGet for Server {
|
||||
not_found: vec![],
|
||||
};
|
||||
|
||||
let access_token = if account_id == access_token.primary_id() {
|
||||
AccessTokenRef::Borrowed(access_token)
|
||||
} else {
|
||||
AccessTokenRef::Owned(
|
||||
self.get_access_token(account_id)
|
||||
.await
|
||||
.caused_by(trc::location!())?,
|
||||
)
|
||||
};
|
||||
|
||||
for id in ids {
|
||||
// Obtain the sieve script object
|
||||
let document_id = id.document_id();
|
||||
@@ -73,10 +84,11 @@ impl QuotaGet for Server {
|
||||
QuotaProperty::Id => Value::Element(id.into()),
|
||||
QuotaProperty::ResourceType => "octets".to_string().into(),
|
||||
QuotaProperty::Used => (self.get_used_quota(account_id).await? as u64).into(),
|
||||
QuotaProperty::HardLimit => access_token.quota.into(),
|
||||
QuotaProperty::HardLimit => access_token.as_ref().quota.into(),
|
||||
QuotaProperty::Scope => "account".to_string().into(),
|
||||
QuotaProperty::Name => access_token.name.to_string().into(),
|
||||
QuotaProperty::Name => access_token.as_ref().name.to_string().into(),
|
||||
QuotaProperty::Description => access_token
|
||||
.as_ref()
|
||||
.description
|
||||
.as_ref()
|
||||
.map(|s| s.to_string())
|
||||
@@ -84,6 +96,9 @@ impl QuotaGet for Server {
|
||||
QuotaProperty::Types => vec![
|
||||
Value::Element(QuotaValue::Types(DataType::Email)),
|
||||
Value::Element(QuotaValue::Types(DataType::SieveScript)),
|
||||
Value::Element(QuotaValue::Types(DataType::FileNode)),
|
||||
Value::Element(QuotaValue::Types(DataType::CalendarEvent)),
|
||||
Value::Element(QuotaValue::Types(DataType::ContactCard)),
|
||||
]
|
||||
.into(),
|
||||
|
||||
@@ -97,3 +112,17 @@ impl QuotaGet for Server {
|
||||
Ok(response)
|
||||
}
|
||||
}
|
||||
|
||||
enum AccessTokenRef<'x> {
|
||||
Owned(Arc<AccessToken>),
|
||||
Borrowed(&'x AccessToken),
|
||||
}
|
||||
|
||||
impl AccessTokenRef<'_> {
|
||||
fn as_ref(&self) -> &AccessToken {
|
||||
match self {
|
||||
AccessTokenRef::Owned(token) => token,
|
||||
AccessTokenRef::Borrowed(token) => token,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -777,6 +777,11 @@ pub trait TestInternalDirectory {
|
||||
async fn create_test_list(&self, login: &str, name: &str, emails: &[&str]) -> u32;
|
||||
async fn set_test_quota(&self, login: &str, quota: u32);
|
||||
async fn add_permissions(&self, login: &str, permissions: impl IntoIterator<Item = Permission>);
|
||||
async fn remove_permissions(
|
||||
&self,
|
||||
login: &str,
|
||||
permissions: impl IntoIterator<Item = Permission>,
|
||||
);
|
||||
async fn add_to_group(&self, login: &str, group: &str) -> ChangedPrincipals;
|
||||
async fn remove_from_group(&self, login: &str, group: &str) -> ChangedPrincipals;
|
||||
async fn remove_test_alias(&self, login: &str, alias: &str);
|
||||
@@ -815,6 +820,10 @@ impl TestInternalDirectory for Store {
|
||||
PrincipalField::Roles,
|
||||
PrincipalValue::String(role.into()),
|
||||
),
|
||||
PrincipalUpdate::add_item(
|
||||
PrincipalField::EnabledPermissions,
|
||||
PrincipalValue::String(Permission::UnlimitedRequests.name().into()),
|
||||
),
|
||||
]))
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -835,6 +844,12 @@ impl TestInternalDirectory for Store {
|
||||
.with_field(
|
||||
PrincipalField::Roles,
|
||||
PrincipalValue::StringList(vec![role.into()]),
|
||||
)
|
||||
.with_field(
|
||||
PrincipalField::EnabledPermissions,
|
||||
PrincipalValue::StringList(vec![
|
||||
Permission::UnlimitedRequests.name().into(),
|
||||
]),
|
||||
),
|
||||
None,
|
||||
None,
|
||||
@@ -935,6 +950,28 @@ impl TestInternalDirectory for Store {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
async fn remove_permissions(
|
||||
&self,
|
||||
login: &str,
|
||||
permissions: impl IntoIterator<Item = Permission>,
|
||||
) {
|
||||
self.update_principal(
|
||||
UpdatePrincipal::by_name(login).with_updates(
|
||||
permissions
|
||||
.into_iter()
|
||||
.map(|p| {
|
||||
PrincipalUpdate::remove_item(
|
||||
PrincipalField::EnabledPermissions,
|
||||
PrincipalValue::String(p.name().to_string()),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
async fn add_to_group(&self, login: &str, group: &str) -> ChangedPrincipals {
|
||||
self.update_principal(UpdatePrincipal::by_name(login).with_updates(vec![
|
||||
PrincipalUpdate::add_item(
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
imap::{ImapConnection, Type},
|
||||
jmap::{JMAPTest, assert_is_empty, mail::mailbox::destroy_all_mailboxes},
|
||||
jmap::{JMAPTest, assert_is_empty},
|
||||
};
|
||||
use common::listener::blocked::BLOCKED_IP_KEY;
|
||||
use directory::Permission;
|
||||
use imap_proto::ResponseType;
|
||||
use jmap_client::{
|
||||
client::{Client, Credentials},
|
||||
@@ -22,27 +23,21 @@ use std::{
|
||||
time::Duration,
|
||||
};
|
||||
use store::write::now;
|
||||
use types::id::Id;
|
||||
|
||||
pub async fn test(params: &mut JMAPTest) {
|
||||
println!("Running Authorization tests...");
|
||||
|
||||
// Create test account
|
||||
let server = params.server.clone();
|
||||
let account_id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com", "john.doe@example.com"],
|
||||
)
|
||||
.await,
|
||||
)
|
||||
.to_string();
|
||||
let account = params.account("jdoe@example.com");
|
||||
|
||||
// Remove unlimited requests permission
|
||||
params
|
||||
.server
|
||||
.store()
|
||||
.remove_permissions(account.name(), [Permission::UnlimitedRequests])
|
||||
.await;
|
||||
params.server.inner.cache.access_tokens.clear();
|
||||
|
||||
// Reset rate limiters
|
||||
params.webhook.clear();
|
||||
@@ -140,7 +135,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
// Valid authentication requests should not be rate limited
|
||||
for _ in 0..110 {
|
||||
Client::new()
|
||||
.credentials(Credentials::basic("jdoe@example.com", "12345"))
|
||||
.credentials(Credentials::basic(account.name(), account.secret()))
|
||||
.accept_invalid_certs(true)
|
||||
.follow_redirects(["127.0.0.1"])
|
||||
.connect("https://127.0.0.1:8899")
|
||||
@@ -150,18 +145,28 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
|
||||
// Login with the correct credentials
|
||||
let client = Client::new()
|
||||
.credentials(Credentials::basic("jdoe@example.com", "12345"))
|
||||
.credentials(Credentials::basic(account.name(), account.secret()))
|
||||
.accept_invalid_certs(true)
|
||||
.follow_redirects(["127.0.0.1"])
|
||||
.connect("https://127.0.0.1:8899")
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(client.session().username(), "jdoe@example.com");
|
||||
assert_eq!(client.session().username(), account.name());
|
||||
assert_eq!(
|
||||
client.session().account(&account_id).unwrap().name(),
|
||||
"jdoe@example.com"
|
||||
client
|
||||
.session()
|
||||
.account(account.id_string())
|
||||
.unwrap()
|
||||
.name(),
|
||||
account.name()
|
||||
);
|
||||
assert!(
|
||||
client
|
||||
.session()
|
||||
.account(account.id_string())
|
||||
.unwrap()
|
||||
.is_personal()
|
||||
);
|
||||
assert!(client.session().account(&account_id).unwrap().is_personal());
|
||||
|
||||
// Uploads up to 5000000 bytes should be allowed
|
||||
assert_eq!(
|
||||
@@ -241,9 +246,16 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
client.upload(None, b"sleep".to_vec(), None).await,
|
||||
Err(jmap_client::Error::Problem(err)) if err.status() == Some(400)));
|
||||
|
||||
// Add unlimited requests permission
|
||||
params
|
||||
.server
|
||||
.store()
|
||||
.add_permissions(account.name(), [Permission::UnlimitedRequests])
|
||||
.await;
|
||||
params.server.inner.cache.access_tokens.clear();
|
||||
|
||||
// Destroy test accounts
|
||||
params.client.set_default_account_id(&account_id);
|
||||
destroy_all_mailboxes(params).await;
|
||||
params.destroy_all_mailboxes(account).await;
|
||||
assert_is_empty(server).await;
|
||||
|
||||
// Check webhook events
|
||||
|
||||
@@ -5,15 +5,11 @@
|
||||
*/
|
||||
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
imap::{
|
||||
ImapConnection, Type,
|
||||
pop::{self, Pop3Connection},
|
||||
},
|
||||
jmap::{
|
||||
JMAPTest, ManagementApi, assert_is_empty,
|
||||
mail::{delivery::SmtpConnection, mailbox::destroy_all_mailboxes},
|
||||
},
|
||||
jmap::{JMAPTest, ManagementApi, assert_is_empty, mail::delivery::SmtpConnection},
|
||||
};
|
||||
use base64::{Engine, engine::general_purpose};
|
||||
use biscuit::{JWT, SingleOrMultiple, jwk::JWKSet};
|
||||
@@ -35,7 +31,6 @@ use jmap_client::{
|
||||
use serde::{Serialize, de::DeserializeOwned};
|
||||
use std::time::{Duration, Instant};
|
||||
use store::ahash::AHashMap;
|
||||
use types::id::Id;
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
#[allow(dead_code)]
|
||||
@@ -50,18 +45,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
|
||||
// Create test account
|
||||
let server = params.server.clone();
|
||||
let john_int_id = server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com"],
|
||||
)
|
||||
.await;
|
||||
let john_id = Id::from(john_int_id).to_string();
|
||||
let account = params.account("jdoe@example.com");
|
||||
|
||||
// Build API
|
||||
let api = ManagementApi::new(8899, "jdoe@example.com", "12345");
|
||||
@@ -145,7 +129,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.connect("https://127.0.0.1:8899")
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(john_client.default_account_id(), john_id);
|
||||
assert_eq!(john_client.default_account_id(), account.id_string());
|
||||
assert!(
|
||||
!john_client
|
||||
.mailbox_query(None::<Filter>, None::<Vec<_>>)
|
||||
@@ -163,7 +147,10 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
let registered_claims = &claims.registered;
|
||||
let private_claims = &claims.private;
|
||||
assert_eq!(registered_claims.issuer, Some(oidc_metadata.issuer));
|
||||
assert_eq!(registered_claims.subject, Some(john_int_id.to_string()));
|
||||
assert_eq!(
|
||||
registered_claims.subject,
|
||||
Some(account.id().document_id().to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
registered_claims.audience,
|
||||
Some(SingleOrMultiple::Single(client_id.to_string()))
|
||||
@@ -324,7 +311,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.connect("https://127.0.0.1:8899")
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(john_client.default_account_id(), john_id);
|
||||
assert_eq!(john_client.default_account_id(), account.id_string());
|
||||
assert!(
|
||||
!john_client
|
||||
.mailbox_query(None::<Filter>, None::<Vec<_>>)
|
||||
@@ -399,8 +386,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.purge_in_memory_store()
|
||||
.await
|
||||
.unwrap();
|
||||
params.client.set_default_account_id(john_id);
|
||||
destroy_all_mailboxes(params).await;
|
||||
params.destroy_all_mailboxes(account).await;
|
||||
assert_is_empty(server).await;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,10 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use crate::jmap::{JMAPTest, ManagementApi, assert_is_empty, server::List};
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
jmap::{JMAPTest, ManagementApi, assert_is_empty, server::List},
|
||||
};
|
||||
use ahash::AHashSet;
|
||||
use common::auth::{AccessToken, TenantInfo};
|
||||
use directory::{
|
||||
@@ -19,6 +22,15 @@ pub async fn test(params: &JMAPTest) {
|
||||
println!("Running permissions tests...");
|
||||
let server = params.server.clone();
|
||||
|
||||
// Remove unlimited requests permission
|
||||
for &account in params.accounts.keys() {
|
||||
params
|
||||
.server
|
||||
.store()
|
||||
.remove_permissions(account, [Permission::UnlimitedRequests])
|
||||
.await;
|
||||
}
|
||||
|
||||
// Prepare management API
|
||||
let api = ManagementApi::new(8899, "admin", "secret");
|
||||
|
||||
@@ -144,7 +156,7 @@ pub async fn test(params: &JMAPTest) {
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap_data()
|
||||
.assert_count(6)
|
||||
.assert_count(12)
|
||||
.assert_exists(
|
||||
"admin",
|
||||
Type::Individual,
|
||||
|
||||
@@ -6,11 +6,7 @@
|
||||
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
jmap::{
|
||||
JMAPTest, assert_is_empty, emails_purge_tombstoned, jmap_raw_request,
|
||||
mail::{delivery::SmtpConnection, mailbox::destroy_all_mailboxes},
|
||||
test_account_login,
|
||||
},
|
||||
jmap::{JMAPTest, assert_is_empty, emails_purge_tombstoned, mail::delivery::SmtpConnection},
|
||||
smtp::queue::QueuedEvents,
|
||||
};
|
||||
use common::config::smtp::queue::QueueName;
|
||||
@@ -20,38 +16,16 @@ use jmap_client::{
|
||||
core::set::{SetErrorType, SetObject},
|
||||
email::EmailBodyPart,
|
||||
};
|
||||
use serde_json::json;
|
||||
use smtp::queue::spool::SmtpSpool;
|
||||
use types::{collection::Collection, id::Id};
|
||||
|
||||
pub async fn test(params: &mut JMAPTest) {
|
||||
println!("Running quota tests...");
|
||||
let server = params.server.clone();
|
||||
let mut account_id = Id::from(0u64);
|
||||
let mut other_account_id = Id::from(0u64);
|
||||
|
||||
for (id, email, password, name) in [
|
||||
(
|
||||
&mut other_account_id,
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
),
|
||||
(
|
||||
&mut account_id,
|
||||
"robert@example.com",
|
||||
"aabbcc",
|
||||
"Robert Foobar",
|
||||
),
|
||||
] {
|
||||
*id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.create_test_user(email, password, name, &[email][..])
|
||||
.await,
|
||||
);
|
||||
}
|
||||
let account = params.account("robert@example.com");
|
||||
let other_account = params.account("jdoe@example.com");
|
||||
|
||||
server
|
||||
.core
|
||||
@@ -65,13 +39,14 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.data
|
||||
.add_to_group("robert@example.com", "jdoe@example.com")
|
||||
.await;
|
||||
server.inner.cache.access_tokens.clear();
|
||||
|
||||
// Delete temporary blobs from previous tests
|
||||
server.core.storage.data.blob_expire_all().await;
|
||||
|
||||
// Test temporary blob quota (3 files)
|
||||
DISABLE_UPLOAD_QUOTA.store(false, std::sync::atomic::Ordering::Relaxed);
|
||||
let client = test_account_login("robert@example.com", "aabbcc").await;
|
||||
let client = account.client();
|
||||
for i in 0..3 {
|
||||
assert_eq!(
|
||||
client
|
||||
@@ -114,16 +89,15 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
server.core.storage.data.blob_expire_all().await;
|
||||
|
||||
// Test JMAP Quotas extension
|
||||
let response = jmap_raw_request(
|
||||
r#"[[ "Quota/get", {
|
||||
"accountId": "$$",
|
||||
"ids": null
|
||||
}, "0" ]]"#
|
||||
.replace("$$", &account_id.to_string()),
|
||||
"robert@example.com",
|
||||
"aabbcc",
|
||||
)
|
||||
.await;
|
||||
let response = account
|
||||
.jmap_method_call(
|
||||
"Quota/get",
|
||||
json!({
|
||||
"ids": null
|
||||
}),
|
||||
)
|
||||
.await
|
||||
.to_string();
|
||||
assert!(response.contains("\"used\":0"), "{}", response);
|
||||
assert!(response.contains("\"hardLimit\":1024"), "{}", response);
|
||||
assert!(response.contains("\"scope\":\"account\""), "{}", response);
|
||||
@@ -168,16 +142,15 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
);
|
||||
|
||||
// Test JMAP Quotas extension
|
||||
let response = jmap_raw_request(
|
||||
r#"[[ "Quota/get", {
|
||||
"accountId": "$$",
|
||||
"ids": null
|
||||
}, "0" ]]"#
|
||||
.replace("$$", &account_id.to_string()),
|
||||
"robert@example.com",
|
||||
"aabbcc",
|
||||
)
|
||||
.await;
|
||||
let response = account
|
||||
.jmap_method_call(
|
||||
"Quota/get",
|
||||
json!({
|
||||
"ids": null
|
||||
}),
|
||||
)
|
||||
.await
|
||||
.to_string();
|
||||
assert!(response.contains("\"used\":1024"), "{}", response);
|
||||
assert!(response.contains("\"hardLimit\":1024"), "{}", response);
|
||||
|
||||
@@ -188,7 +161,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
emails_purge_tombstoned(&server).await;
|
||||
assert_eq!(
|
||||
server
|
||||
.get_used_quota(account_id.document_id())
|
||||
.get_used_quota(account.id().document_id())
|
||||
.await
|
||||
.unwrap(),
|
||||
0
|
||||
@@ -231,16 +204,16 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
|
||||
// Recalculate quota
|
||||
let prev_quota = server
|
||||
.get_used_quota(account_id.document_id())
|
||||
.get_used_quota(account.id().document_id())
|
||||
.await
|
||||
.unwrap();
|
||||
server
|
||||
.recalculate_quota(account_id.document_id())
|
||||
.recalculate_quota(account.id().document_id())
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
server
|
||||
.get_used_quota(account_id.document_id())
|
||||
.get_used_quota(account.id().document_id())
|
||||
.await
|
||||
.unwrap(),
|
||||
prev_quota
|
||||
@@ -253,14 +226,14 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
emails_purge_tombstoned(&server).await;
|
||||
assert_eq!(
|
||||
server
|
||||
.get_used_quota(account_id.document_id())
|
||||
.get_used_quota(account.id().document_id())
|
||||
.await
|
||||
.unwrap(),
|
||||
0
|
||||
);
|
||||
|
||||
// Test Email/copy quota
|
||||
let other_client = test_account_login("jdoe@example.com", "12345").await;
|
||||
let other_client = other_account.client();
|
||||
let mut other_message_ids = Vec::new();
|
||||
let mut message_ids = Vec::new();
|
||||
for i in 0..3 {
|
||||
@@ -286,7 +259,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
message_ids.push(
|
||||
client
|
||||
.email_copy(
|
||||
other_account_id.to_string(),
|
||||
other_account.id_string(),
|
||||
id,
|
||||
vec![&inbox_id],
|
||||
None::<Vec<String>>,
|
||||
@@ -300,7 +273,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
assert_over_quota(
|
||||
client
|
||||
.email_copy(
|
||||
other_account_id.to_string(),
|
||||
other_account.id_string(),
|
||||
&other_message_ids[2],
|
||||
vec![&inbox_id],
|
||||
None::<Vec<String>>,
|
||||
@@ -316,7 +289,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
emails_purge_tombstoned(&server).await;
|
||||
assert_eq!(
|
||||
server
|
||||
.get_used_quota(account_id.document_id())
|
||||
.get_used_quota(account.id().document_id())
|
||||
.await
|
||||
.unwrap(),
|
||||
0
|
||||
@@ -339,13 +312,13 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.await;
|
||||
}
|
||||
let quota = server
|
||||
.get_used_quota(account_id.document_id())
|
||||
.get_used_quota(account.id().document_id())
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(quota > 0 && quota <= 1024, "Quota is {}", quota);
|
||||
assert_eq!(
|
||||
server
|
||||
.get_document_ids(account_id.document_id(), Collection::Email)
|
||||
.get_document_ids(account.id().document_id(), Collection::Email)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
@@ -356,10 +329,9 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
DISABLE_UPLOAD_QUOTA.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||
|
||||
// Remove test data
|
||||
for account_id in [&account_id, &other_account_id] {
|
||||
params.client.set_default_account_id(account_id.to_string());
|
||||
destroy_all_mailboxes(params).await;
|
||||
}
|
||||
params.destroy_all_mailboxes(account).await;
|
||||
params.destroy_all_mailboxes(other_account).await;
|
||||
|
||||
for event in server.all_queued_messages().await.messages {
|
||||
server
|
||||
.read_message(event.queue_id, QueueName::default())
|
||||
|
||||
@@ -4,38 +4,19 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
jmap::{JMAPTest, assert_is_empty, jmap_json_request, mail::mailbox::destroy_all_mailboxes},
|
||||
};
|
||||
use crate::jmap::{JMAPTest, assert_is_empty};
|
||||
use email::mailbox::INBOX_ID;
|
||||
use serde_json::Value;
|
||||
use serde_json::{Value, json};
|
||||
use types::id::Id;
|
||||
|
||||
pub async fn test(params: &mut JMAPTest) {
|
||||
println!("Running blob tests...");
|
||||
let server = params.server.clone();
|
||||
let account_id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com"],
|
||||
)
|
||||
.await,
|
||||
);
|
||||
let account = params.account("jdoe@example.com");
|
||||
server.core.storage.data.blob_expire_all().await;
|
||||
|
||||
// Blob/set simple test
|
||||
let response = jmap_json_request(
|
||||
r#"[[
|
||||
"Blob/upload",
|
||||
{
|
||||
"accountId": "$$",
|
||||
let response = account.jmap_method_call("Blob/upload", json!({
|
||||
"create": {
|
||||
"abc": {
|
||||
"data" : [
|
||||
@@ -46,14 +27,8 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
"type": "image/png"
|
||||
}
|
||||
}
|
||||
},
|
||||
"R1"
|
||||
]]"#
|
||||
.replace("$$", &account_id.to_string()),
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
)
|
||||
.await;
|
||||
})).await;
|
||||
|
||||
assert_eq!(
|
||||
response
|
||||
.pointer("/methodResponses/0/1/created/abc/type")
|
||||
@@ -74,11 +49,10 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
);
|
||||
|
||||
// Blob/get simple test
|
||||
let blob_id = jmap_json_request(
|
||||
r#"[[
|
||||
let blob_id = account
|
||||
.jmap_method_call(
|
||||
"Blob/upload",
|
||||
{
|
||||
"accountId": "$$",
|
||||
json!({
|
||||
"create": {
|
||||
"abc": {
|
||||
"data" : [
|
||||
@@ -88,61 +62,48 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
]
|
||||
}
|
||||
}
|
||||
}),
|
||||
)
|
||||
.await
|
||||
.pointer("/methodResponses/0/1/created/abc/id")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap()
|
||||
.to_string();
|
||||
|
||||
let response = account
|
||||
.jmap_method_calls(json!([[
|
||||
"Blob/get",
|
||||
{
|
||||
"ids" : [
|
||||
blob_id
|
||||
],
|
||||
"properties" : [
|
||||
"data:asText",
|
||||
"digest:sha",
|
||||
"size"
|
||||
]
|
||||
},
|
||||
"R1"
|
||||
]]"#
|
||||
.replace("$$", &account_id.to_string()),
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
)
|
||||
.await
|
||||
.pointer("/methodResponses/0/1/created/abc/id")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap()
|
||||
.to_string();
|
||||
|
||||
let response = jmap_json_request(
|
||||
r#"[
|
||||
[
|
||||
"Blob/get",
|
||||
{
|
||||
"accountId" : "$$",
|
||||
"ids" : [
|
||||
"%%"
|
||||
],
|
||||
"properties" : [
|
||||
"data:asText",
|
||||
"digest:sha",
|
||||
"size"
|
||||
]
|
||||
},
|
||||
"R1"
|
||||
],
|
||||
[
|
||||
"Blob/get",
|
||||
{
|
||||
"accountId" : "$$",
|
||||
"ids" : [
|
||||
"%%"
|
||||
],
|
||||
"properties" : [
|
||||
"data:asText",
|
||||
"digest:sha",
|
||||
"digest:sha-256",
|
||||
"size"
|
||||
],
|
||||
"offset" : 4,
|
||||
"length" : 9
|
||||
},
|
||||
"R2"
|
||||
]
|
||||
]"#
|
||||
.replace("$$", &account_id.to_string())
|
||||
.replace("%%", &blob_id),
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
)
|
||||
.await;
|
||||
],
|
||||
[
|
||||
"Blob/get",
|
||||
{
|
||||
"ids" : [
|
||||
blob_id
|
||||
],
|
||||
"properties" : [
|
||||
"data:asText",
|
||||
"digest:sha",
|
||||
"digest:sha-256",
|
||||
"size"
|
||||
],
|
||||
"offset" : 4,
|
||||
"length" : 9
|
||||
},
|
||||
"R2"
|
||||
]
|
||||
]))
|
||||
.await;
|
||||
|
||||
for (pointer, expected) in [
|
||||
(
|
||||
@@ -174,84 +135,76 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
})
|
||||
.unwrap_or_default(),
|
||||
expected,
|
||||
"Pointer {pointer:?} Response: {}",
|
||||
serde_json::to_string_pretty(&response).unwrap()
|
||||
"Pointer {pointer:?} Response: {response:?}",
|
||||
);
|
||||
}
|
||||
|
||||
server.core.storage.data.blob_expire_all().await;
|
||||
|
||||
// Blob/upload Complex Example
|
||||
let response = jmap_json_request(
|
||||
r##"[
|
||||
[
|
||||
"Blob/upload",
|
||||
{
|
||||
"accountId" : "$$",
|
||||
"create": {
|
||||
"b4": {
|
||||
"data": [
|
||||
let response = account
|
||||
.jmap_method_calls(json!([
|
||||
[
|
||||
"Blob/upload",
|
||||
{
|
||||
"create": {
|
||||
"b4": {
|
||||
"data": [
|
||||
{
|
||||
"data:asText": "The quick brown fox jumped over the lazy dog."
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"S4"
|
||||
],
|
||||
[
|
||||
"Blob/upload",
|
||||
{
|
||||
"create": {
|
||||
"cat": {
|
||||
"data": [
|
||||
{
|
||||
"data:asText": "The quick brown fox jumped over the lazy dog."
|
||||
"data:asText": "How"
|
||||
},
|
||||
{
|
||||
"blobId": "#b4",
|
||||
"length": 7,
|
||||
"offset": 3
|
||||
},
|
||||
{
|
||||
"data:asText": "was t"
|
||||
},
|
||||
{
|
||||
"blobId": "#b4",
|
||||
"length": 1,
|
||||
"offset": 1
|
||||
},
|
||||
{
|
||||
"data:asBase64": "YXQ/"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"S4"
|
||||
}
|
||||
},
|
||||
"CAT"
|
||||
],
|
||||
[
|
||||
"Blob/get",
|
||||
{
|
||||
"properties": [
|
||||
"data:asText",
|
||||
"size"
|
||||
],
|
||||
[
|
||||
"Blob/upload",
|
||||
{
|
||||
"accountId" : "$$",
|
||||
"create": {
|
||||
"cat": {
|
||||
"data": [
|
||||
{
|
||||
"data:asText": "How"
|
||||
},
|
||||
{
|
||||
"blobId": "#b4",
|
||||
"length": 7,
|
||||
"offset": 3
|
||||
},
|
||||
{
|
||||
"data:asText": "was t"
|
||||
},
|
||||
{
|
||||
"blobId": "#b4",
|
||||
"length": 1,
|
||||
"offset": 1
|
||||
},
|
||||
{
|
||||
"data:asBase64": "YXQ/"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"CAT"
|
||||
],
|
||||
[
|
||||
"Blob/get",
|
||||
{
|
||||
"accountId" : "$$",
|
||||
"properties": [
|
||||
"data:asText",
|
||||
"size"
|
||||
],
|
||||
"ids": [
|
||||
"#cat"
|
||||
]
|
||||
},
|
||||
"G4"
|
||||
]
|
||||
]"##
|
||||
.replace("$$", &account_id.to_string()),
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
)
|
||||
.await;
|
||||
"ids": [
|
||||
"#cat"
|
||||
]
|
||||
},
|
||||
"G4"
|
||||
]
|
||||
]))
|
||||
.await;
|
||||
|
||||
for (pointer, expected) in [
|
||||
(
|
||||
@@ -276,12 +229,10 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
server.core.storage.data.blob_expire_all().await;
|
||||
|
||||
// Blob/get Example with Range and Encoding Errors
|
||||
let response = jmap_json_request(
|
||||
r##"[
|
||||
let response = account.jmap_method_calls(json!([
|
||||
[
|
||||
"Blob/upload",
|
||||
{
|
||||
"accountId" : "$$",
|
||||
"create": {
|
||||
"b1": {
|
||||
"data": [
|
||||
@@ -305,7 +256,6 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
[
|
||||
"Blob/get",
|
||||
{
|
||||
"accountId" : "$$",
|
||||
"ids": [
|
||||
"#b1",
|
||||
"#b2"
|
||||
@@ -316,7 +266,6 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
[
|
||||
"Blob/get",
|
||||
{
|
||||
"accountId" : "$$",
|
||||
"ids": [
|
||||
"#b1",
|
||||
"#b2"
|
||||
@@ -331,7 +280,6 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
[
|
||||
"Blob/get",
|
||||
{
|
||||
"accountId" : "$$",
|
||||
"ids": [
|
||||
"#b1",
|
||||
"#b2"
|
||||
@@ -346,7 +294,6 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
[
|
||||
"Blob/get",
|
||||
{
|
||||
"accountId" : "$$",
|
||||
"offset": 0,
|
||||
"length": 5,
|
||||
"ids": [
|
||||
@@ -359,7 +306,6 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
[
|
||||
"Blob/get",
|
||||
{
|
||||
"accountId" : "$$",
|
||||
"offset": 20,
|
||||
"length": 100,
|
||||
"ids": [
|
||||
@@ -369,12 +315,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
},
|
||||
"G5"
|
||||
]
|
||||
]"##
|
||||
.replace("$$", &account_id.to_string()),
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
)
|
||||
.await;
|
||||
])).await;
|
||||
|
||||
for (pointer, expected) in [
|
||||
(
|
||||
@@ -415,9 +356,8 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
server.core.storage.data.blob_expire_all().await;
|
||||
|
||||
// Blob/lookup
|
||||
params.client.set_default_account_id(account_id.to_string());
|
||||
let blob_id = params
|
||||
.client
|
||||
let client = account.client();
|
||||
let blob_id = client
|
||||
.email_import(
|
||||
concat!(
|
||||
"From: bill@example.com\r\n",
|
||||
@@ -437,29 +377,22 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.unwrap()
|
||||
.take_blob_id();
|
||||
|
||||
let response = jmap_json_request(
|
||||
r#"[[
|
||||
"Blob/lookup",
|
||||
{
|
||||
"accountId" : "$$",
|
||||
"typeNames": [
|
||||
"Mailbox",
|
||||
"Thread",
|
||||
"Email"
|
||||
],
|
||||
"ids": [
|
||||
"%%",
|
||||
"not-a-blob"
|
||||
]
|
||||
},
|
||||
"R1"
|
||||
]]"#
|
||||
.replace("$$", &account_id.to_string())
|
||||
.replace("%%", &blob_id),
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
)
|
||||
.await;
|
||||
let response = account
|
||||
.jmap_method_call(
|
||||
"Blob/lookup",
|
||||
json!({
|
||||
"typeNames": [
|
||||
"Mailbox",
|
||||
"Thread",
|
||||
"Email"
|
||||
],
|
||||
"ids": [
|
||||
blob_id,
|
||||
"not-a-blob"
|
||||
]
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
|
||||
for pointer in [
|
||||
"/methodResponses/0/1/list/0/matchedIds/Email",
|
||||
@@ -478,7 +411,6 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
}
|
||||
|
||||
// Remove test data
|
||||
params.client.set_default_account_id(account_id.to_string());
|
||||
destroy_all_mailboxes(params).await;
|
||||
params.destroy_all_mailboxes(account).await;
|
||||
assert_is_empty(server).await;
|
||||
}
|
||||
|
||||
@@ -4,46 +4,22 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
jmap::{
|
||||
JMAPTest, assert_is_empty,
|
||||
mail::{delivery::SmtpConnection, mailbox::destroy_all_mailboxes},
|
||||
test_account_login,
|
||||
},
|
||||
};
|
||||
use crate::jmap::{JMAPTest, assert_is_empty, mail::delivery::SmtpConnection};
|
||||
use email::mailbox::INBOX_ID;
|
||||
use futures::StreamExt;
|
||||
|
||||
use jmap_client::{TypeState, event_source::Changes, mailbox::Role};
|
||||
use std::time::Duration;
|
||||
use store::ahash::AHashSet;
|
||||
use types::id::Id;
|
||||
|
||||
use tokio::sync::mpsc;
|
||||
use types::id::Id;
|
||||
|
||||
pub async fn test(params: &mut JMAPTest) {
|
||||
println!("Running EventSource tests...");
|
||||
|
||||
// Create test account
|
||||
let server = params.server.clone();
|
||||
let account_id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com"],
|
||||
)
|
||||
.await,
|
||||
)
|
||||
.to_string();
|
||||
|
||||
let client = test_account_login("jdoe@example.com", "12345").await;
|
||||
let account = params.account("jdoe@example.com");
|
||||
let client = account.client();
|
||||
|
||||
let mut changes = client
|
||||
.event_source(None::<Vec<_>>, false, 1.into(), None)
|
||||
@@ -69,7 +45,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.await
|
||||
.unwrap()
|
||||
.take_id();
|
||||
assert_state(&mut event_rx, &account_id, &[TypeState::Mailbox]).await;
|
||||
assert_state(&mut event_rx, account.id_string(), &[TypeState::Mailbox]).await;
|
||||
|
||||
// Multiple changes should be grouped and delivered in intervals
|
||||
for num in 0..5 {
|
||||
@@ -78,7 +54,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
assert_state(&mut event_rx, &account_id, &[TypeState::Mailbox]).await;
|
||||
assert_state(&mut event_rx, account.id_string(), &[TypeState::Mailbox]).await;
|
||||
assert_ping(&mut event_rx).await; // Pings are only received in cfg(test)
|
||||
|
||||
// Ingest email and expect state change
|
||||
@@ -100,7 +76,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
|
||||
assert_state(
|
||||
&mut event_rx,
|
||||
&account_id,
|
||||
account.id_string(),
|
||||
&[
|
||||
TypeState::EmailDelivery,
|
||||
TypeState::Email,
|
||||
@@ -113,25 +89,23 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
|
||||
// Destroy mailbox
|
||||
client.mailbox_destroy(&mailbox_id, true).await.unwrap();
|
||||
assert_state(&mut event_rx, &account_id, &[TypeState::Mailbox]).await;
|
||||
assert_state(&mut event_rx, account.id_string(), &[TypeState::Mailbox]).await;
|
||||
|
||||
// Destroy Inbox
|
||||
params.client.set_default_account_id(account_id.to_string());
|
||||
params
|
||||
.client
|
||||
client
|
||||
.mailbox_destroy(&Id::from(INBOX_ID).to_string(), true)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_state(
|
||||
&mut event_rx,
|
||||
&account_id,
|
||||
account.id_string(),
|
||||
&[TypeState::Email, TypeState::Thread, TypeState::Mailbox],
|
||||
)
|
||||
.await;
|
||||
assert_ping(&mut event_rx).await;
|
||||
assert_ping(&mut event_rx).await;
|
||||
|
||||
destroy_all_mailboxes(params).await;
|
||||
params.destroy_all_mailboxes(account).await;
|
||||
assert_is_empty(server).await;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
|
||||
use crate::{
|
||||
AssertConfig, add_test_certs,
|
||||
directory::internal::TestInternalDirectory,
|
||||
jmap::{JMAPTest, assert_is_empty, mail::mailbox::destroy_all_mailboxes, test_account_login},
|
||||
jmap::{JMAPTest, assert_is_empty},
|
||||
};
|
||||
use base64::{Engine, engine::general_purpose};
|
||||
use common::{Caches, Core, Data, Inner, config::server::Listeners, listener::SessionData};
|
||||
@@ -56,22 +55,8 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
|
||||
// Create test account
|
||||
let server = params.server.clone();
|
||||
let account_id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com"],
|
||||
)
|
||||
.await,
|
||||
);
|
||||
|
||||
params.client.set_default_account_id(account_id);
|
||||
let client = test_account_login("jdoe@example.com", "12345").await;
|
||||
let account = params.account("jdoe@example.com");
|
||||
let client = account.client();
|
||||
|
||||
// Create channels
|
||||
let (event_tx, mut event_rx) = mpsc::channel::<PushMessage>(100);
|
||||
@@ -140,7 +125,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.unwrap()
|
||||
.take_id();
|
||||
|
||||
assert_state(&mut event_rx, &account_id, &[DataType::Mailbox]).await;
|
||||
assert_state(&mut event_rx, account.id(), &[DataType::Mailbox]).await;
|
||||
|
||||
// Receive states just for the requested types
|
||||
client
|
||||
@@ -194,14 +179,14 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.unwrap();
|
||||
tokio::time::sleep(Duration::from_millis(200)).await;
|
||||
push_server.fail_requests.store(false, Ordering::Relaxed);
|
||||
assert_state(&mut event_rx, &account_id, &[DataType::Mailbox]).await;
|
||||
assert_state(&mut event_rx, account.id(), &[DataType::Mailbox]).await;
|
||||
|
||||
// Make a mailbox change and expect state change
|
||||
client
|
||||
.mailbox_rename(&mailbox_id, "My Mailbox")
|
||||
.await
|
||||
.unwrap();
|
||||
assert_state(&mut event_rx, &account_id, &[DataType::Mailbox]).await;
|
||||
assert_state(&mut event_rx, account.id(), &[DataType::Mailbox]).await;
|
||||
//expect_nothing(&mut event_rx).await;
|
||||
|
||||
// Multiple change updates should be grouped and pushed in intervals
|
||||
@@ -211,7 +196,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
assert_state(&mut event_rx, &account_id, &[DataType::Mailbox]).await;
|
||||
assert_state(&mut event_rx, account.id(), &[DataType::Mailbox]).await;
|
||||
expect_nothing(&mut event_rx).await;
|
||||
|
||||
// Destroy mailbox
|
||||
@@ -219,7 +204,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
client.mailbox_destroy(&mailbox_id, true).await.unwrap();
|
||||
expect_nothing(&mut event_rx).await;
|
||||
|
||||
destroy_all_mailboxes(params).await;
|
||||
params.destroy_all_mailboxes(account).await;
|
||||
assert_is_empty(server).await;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use crate::jmap::{JMAPTest, assert_is_empty};
|
||||
use ahash::AHashSet;
|
||||
use futures::StreamExt;
|
||||
use jmap_client::{
|
||||
@@ -15,35 +16,15 @@ use jmap_client::{
|
||||
},
|
||||
};
|
||||
use std::time::Duration;
|
||||
use types::id::Id;
|
||||
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
jmap::{JMAPTest, assert_is_empty, mail::mailbox::destroy_all_mailboxes, test_account_login},
|
||||
};
|
||||
|
||||
pub async fn test(params: &mut JMAPTest) {
|
||||
println!("Running WebSockets tests...");
|
||||
let server = params.server.clone();
|
||||
|
||||
// Authenticate all accounts
|
||||
let account_id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com"],
|
||||
)
|
||||
.await,
|
||||
)
|
||||
.to_string();
|
||||
let client = test_account_login("jdoe@example.com", "12345").await;
|
||||
let account = params.account("jdoe@example.com");
|
||||
let client = account.client();
|
||||
|
||||
let mut ws_stream = client.connect_ws().await.unwrap();
|
||||
|
||||
@@ -86,7 +67,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.mailbox_update_sort_order(&mailbox_id, 1)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_state(&mut stream_rx, &account_id, &[TypeState::Mailbox]).await;
|
||||
assert_state(&mut stream_rx, account.id_string(), &[TypeState::Mailbox]).await;
|
||||
|
||||
// Multiple changes should be grouped and delivered in intervals
|
||||
for num in 0..5 {
|
||||
@@ -96,7 +77,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.unwrap();
|
||||
}
|
||||
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||
assert_state(&mut stream_rx, &account_id, &[TypeState::Mailbox]).await;
|
||||
assert_state(&mut stream_rx, account.id_string(), &[TypeState::Mailbox]).await;
|
||||
expect_nothing(&mut stream_rx).await;
|
||||
|
||||
// Disable push notifications
|
||||
@@ -116,8 +97,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.unwrap();
|
||||
expect_nothing(&mut stream_rx).await;
|
||||
|
||||
params.client.set_default_account_id(account_id);
|
||||
destroy_all_mailboxes(params).await;
|
||||
params.destroy_all_mailboxes(account).await;
|
||||
assert_is_empty(server).await;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
jmap::{JMAPTest, assert_is_empty, mail::mailbox::destroy_all_mailboxes, test_account_login},
|
||||
jmap::{JMAPTest, assert_is_empty},
|
||||
};
|
||||
use ::email::mailbox::{INBOX_ID, TRASH_ID};
|
||||
use jmap_client::{
|
||||
@@ -30,62 +30,27 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
let inbox_id = Id::new(INBOX_ID as u64).to_string();
|
||||
let trash_id = Id::new(TRASH_ID as u64).to_string();
|
||||
|
||||
let john_id: Id = server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com"],
|
||||
)
|
||||
.await
|
||||
.into();
|
||||
let jane_id: Id = server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.create_test_user(
|
||||
"jane.smith@example.com",
|
||||
"abcde",
|
||||
"Jane Smith",
|
||||
&["jane.smith@example.com"],
|
||||
)
|
||||
.await
|
||||
.into();
|
||||
let bill_id: Id = server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.create_test_user(
|
||||
"bill@example.com",
|
||||
"098765",
|
||||
"Bill Foobar",
|
||||
&["bill@example.com"],
|
||||
)
|
||||
.await
|
||||
.into();
|
||||
let sales_id: Id = server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.create_test_group("sales@example.com", "Sales Group", &["sales@example.com"])
|
||||
.await
|
||||
.into();
|
||||
let john = params.account("jdoe@example.com");
|
||||
let jane = params.account("jane.smith@example.com");
|
||||
let bill = params.account("bill@example.com");
|
||||
let sales = params.account("sales@example.com");
|
||||
|
||||
// Authenticate all accounts
|
||||
let mut john_client = test_account_login("jdoe@example.com", "12345").await;
|
||||
let mut jane_client = test_account_login("jane.smith@example.com", "abcde").await;
|
||||
let mut bill_client = test_account_login("bill@example.com", "098765").await;
|
||||
let mut john_client = john.client_owned().await;
|
||||
let mut jane_client = jane.client_owned().await;
|
||||
let mut bill_client = bill.client_owned().await;
|
||||
|
||||
// Insert two emails in each account
|
||||
let mut email_ids = AHashMap::default();
|
||||
for (client, account_id, name) in [
|
||||
(&mut john_client, &john_id, "john"),
|
||||
(&mut jane_client, &jane_id, "jane"),
|
||||
(&mut bill_client, &bill_id, "bill"),
|
||||
(&mut params.client, &sales_id, "sales"),
|
||||
(&mut john_client, john.id(), "john"),
|
||||
(&mut jane_client, jane.id(), "jane"),
|
||||
(&mut bill_client, bill.id(), "bill"),
|
||||
(
|
||||
&mut params.account("admin").client_owned().await,
|
||||
sales.id(),
|
||||
"sales",
|
||||
),
|
||||
] {
|
||||
let user_name = client.session().username().to_string();
|
||||
let mut ids = Vec::with_capacity(2);
|
||||
@@ -133,7 +98,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
);
|
||||
assert_forbidden(
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.email_get(
|
||||
email_ids.get("jane").unwrap().first().unwrap(),
|
||||
[Property::Subject].into(),
|
||||
@@ -142,13 +107,13 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
);
|
||||
assert_forbidden(
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.mailbox_get(&inbox_id, None::<Vec<_>>)
|
||||
.await,
|
||||
);
|
||||
assert_forbidden(
|
||||
john_client
|
||||
.set_default_account_id(sales_id.to_string())
|
||||
.set_default_account_id(sales.id_string())
|
||||
.email_get(
|
||||
email_ids.get("sales").unwrap().first().unwrap(),
|
||||
[Property::Subject].into(),
|
||||
@@ -157,27 +122,27 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
);
|
||||
assert_forbidden(
|
||||
john_client
|
||||
.set_default_account_id(sales_id.to_string())
|
||||
.set_default_account_id(sales.id_string())
|
||||
.mailbox_get(&inbox_id, None::<Vec<_>>)
|
||||
.await,
|
||||
);
|
||||
assert_forbidden(
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.email_query(None::<Filter>, None::<Vec<_>>)
|
||||
.await,
|
||||
);
|
||||
|
||||
// Jane grants Inbox ReadItems access to John
|
||||
jane_client
|
||||
.mailbox_update_acl(&inbox_id, &john_id.to_string(), [ACL::ReadItems])
|
||||
.mailbox_update_acl(&inbox_id, john.id_string(), [ACL::ReadItems])
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// John should have ReadItems access to Inbox
|
||||
assert_eq!(
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.email_get(
|
||||
email_ids.get("jane").unwrap().first().unwrap(),
|
||||
[Property::Subject].into(),
|
||||
@@ -191,7 +156,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
);
|
||||
assert_eq!(
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.email_query(None::<Filter>, None::<Vec<_>>)
|
||||
.await
|
||||
.unwrap()
|
||||
@@ -204,7 +169,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
assert_eq!(
|
||||
john_client
|
||||
.session()
|
||||
.account(&jane_id.to_string())
|
||||
.account(jane.id_string())
|
||||
.unwrap()
|
||||
.name(),
|
||||
"jane.smith@example.com"
|
||||
@@ -213,7 +178,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
// John should not have access to emails in Jane's Trash folder
|
||||
assert!(
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.email_get(
|
||||
email_ids.get("jane").unwrap().last().unwrap(),
|
||||
[Property::Subject].into(),
|
||||
@@ -234,8 +199,8 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.unwrap()
|
||||
.take_blob_id();
|
||||
john_client
|
||||
.set_default_account_id(john_id.to_string())
|
||||
.blob_copy(jane_id.to_string(), &blob_id)
|
||||
.set_default_account_id(john.id_string())
|
||||
.blob_copy(jane.id_string(), &blob_id)
|
||||
.await
|
||||
.unwrap();
|
||||
let blob_id = jane_client
|
||||
@@ -249,19 +214,19 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.take_blob_id();
|
||||
assert_forbidden(
|
||||
john_client
|
||||
.set_default_account_id(john_id.to_string())
|
||||
.blob_copy(jane_id.to_string(), &blob_id)
|
||||
.set_default_account_id(john.id_string())
|
||||
.blob_copy(jane.id_string(), &blob_id)
|
||||
.await,
|
||||
);
|
||||
|
||||
// John only has ReadItems access to Inbox
|
||||
jane_client
|
||||
.mailbox_update_acl(&inbox_id, &john_id.to_string(), [ACL::ReadItems])
|
||||
.mailbox_update_acl(&inbox_id, john.id_string(), [ACL::ReadItems])
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.mailbox_get(&inbox_id, [mailbox::Property::MyRights].into())
|
||||
.await
|
||||
.unwrap()
|
||||
@@ -274,9 +239,9 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
|
||||
// Try to add items using import and copy
|
||||
let blob_id = john_client
|
||||
.set_default_account_id(john_id.to_string())
|
||||
.set_default_account_id(john.id_string())
|
||||
.upload(
|
||||
Some(&john_id.to_string()),
|
||||
Some(john.id_string()),
|
||||
concat!(
|
||||
"From: acl_test@example.com\r\n",
|
||||
"To: jane.smith@example.com\r\n",
|
||||
@@ -291,9 +256,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.await
|
||||
.unwrap()
|
||||
.take_blob_id();
|
||||
let mut request = john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.build();
|
||||
let mut request = john_client.set_default_account_id(jane.id_string()).build();
|
||||
let email_id = request
|
||||
.import_email()
|
||||
.email(&blob_id)
|
||||
@@ -308,9 +271,9 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
);
|
||||
assert_forbidden(
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.email_copy(
|
||||
&john_id.to_string(),
|
||||
john.id_string(),
|
||||
email_ids.get("john").unwrap().last().unwrap(),
|
||||
[&inbox_id],
|
||||
None::<Vec<&str>>,
|
||||
@@ -321,17 +284,11 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
|
||||
// Grant access and try again
|
||||
jane_client
|
||||
.mailbox_update_acl(
|
||||
&inbox_id,
|
||||
&john_id.to_string(),
|
||||
[ACL::ReadItems, ACL::AddItems],
|
||||
)
|
||||
.mailbox_update_acl(&inbox_id, john.id_string(), [ACL::ReadItems, ACL::AddItems])
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let mut request = john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.build();
|
||||
let mut request = john_client.set_default_account_id(jane.id_string()).build();
|
||||
let email_id = request
|
||||
.import_email()
|
||||
.email(&blob_id)
|
||||
@@ -345,9 +302,9 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.unwrap()
|
||||
.take_id();
|
||||
let email_id_2 = john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.email_copy(
|
||||
&john_id.to_string(),
|
||||
john.id_string(),
|
||||
email_ids.get("john").unwrap().last().unwrap(),
|
||||
[&inbox_id],
|
||||
None::<Vec<&str>>,
|
||||
@@ -381,20 +338,20 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
// Try removing items
|
||||
assert_forbidden(
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.email_destroy(&email_id)
|
||||
.await,
|
||||
);
|
||||
jane_client
|
||||
.mailbox_update_acl(
|
||||
&inbox_id,
|
||||
&john_id.to_string(),
|
||||
john.id_string(),
|
||||
[ACL::ReadItems, ACL::AddItems, ACL::RemoveItems],
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.email_destroy(&email_id)
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -402,14 +359,14 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
// Try to set keywords
|
||||
assert_forbidden(
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.email_set_keyword(&email_id_2, "$seen", true)
|
||||
.await,
|
||||
);
|
||||
jane_client
|
||||
.mailbox_update_acl(
|
||||
&inbox_id,
|
||||
&john_id.to_string(),
|
||||
john.id_string(),
|
||||
[
|
||||
ACL::ReadItems,
|
||||
ACL::AddItems,
|
||||
@@ -420,12 +377,12 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.await
|
||||
.unwrap();
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.email_set_keyword(&email_id_2, "$seen", true)
|
||||
.await
|
||||
.unwrap();
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.email_set_keyword(&email_id_2, "my-keyword", true)
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -433,14 +390,14 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
// Try to create a child
|
||||
assert_forbidden(
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.mailbox_create("John's mailbox", None::<&str>, Role::None)
|
||||
.await,
|
||||
);
|
||||
jane_client
|
||||
.mailbox_update_acl(
|
||||
&inbox_id,
|
||||
&john_id.to_string(),
|
||||
john.id_string(),
|
||||
[
|
||||
ACL::ReadItems,
|
||||
ACL::AddItems,
|
||||
@@ -452,7 +409,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.await
|
||||
.unwrap();
|
||||
let mailbox_id = john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.mailbox_create("John's mailbox", Some(&inbox_id), Role::None)
|
||||
.await
|
||||
.unwrap()
|
||||
@@ -461,20 +418,16 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
// Try renaming a mailbox
|
||||
assert_forbidden(
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.mailbox_rename(&mailbox_id, "John's private mailbox")
|
||||
.await,
|
||||
);
|
||||
jane_client
|
||||
.mailbox_update_acl(
|
||||
&mailbox_id,
|
||||
&john_id.to_string(),
|
||||
[ACL::ReadItems, ACL::Rename],
|
||||
)
|
||||
.mailbox_update_acl(&mailbox_id, john.id_string(), [ACL::ReadItems, ACL::Rename])
|
||||
.await
|
||||
.unwrap();
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.mailbox_rename(&mailbox_id, "John's private mailbox")
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -482,20 +435,20 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
// Try moving a message
|
||||
assert_forbidden(
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.email_set_mailbox(&email_id_2, &mailbox_id, true)
|
||||
.await,
|
||||
);
|
||||
jane_client
|
||||
.mailbox_update_acl(
|
||||
&mailbox_id,
|
||||
&john_id.to_string(),
|
||||
john.id_string(),
|
||||
[ACL::ReadItems, ACL::Rename, ACL::AddItems],
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.email_set_mailbox(&email_id_2, &mailbox_id, true)
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -503,28 +456,28 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
// Try deleting a mailbox
|
||||
assert_forbidden(
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.mailbox_destroy(&mailbox_id, true)
|
||||
.await,
|
||||
);
|
||||
jane_client
|
||||
.mailbox_update_acl(
|
||||
&mailbox_id,
|
||||
&john_id.to_string(),
|
||||
john.id_string(),
|
||||
[ACL::ReadItems, ACL::Rename, ACL::AddItems, ACL::Delete],
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_forbidden(
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.mailbox_destroy(&mailbox_id, true)
|
||||
.await,
|
||||
);
|
||||
jane_client
|
||||
.mailbox_update_acl(
|
||||
&mailbox_id,
|
||||
&john_id.to_string(),
|
||||
john.id_string(),
|
||||
[
|
||||
ACL::ReadItems,
|
||||
ACL::Rename,
|
||||
@@ -536,7 +489,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.await
|
||||
.unwrap();
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.mailbox_destroy(&mailbox_id, true)
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -544,20 +497,20 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
// Try changing ACL
|
||||
assert_forbidden(
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.mailbox_update_acl(&inbox_id, &bill_id.to_string(), [ACL::ReadItems])
|
||||
.set_default_account_id(jane.id_string())
|
||||
.mailbox_update_acl(&inbox_id, bill.id_string(), [ACL::ReadItems])
|
||||
.await,
|
||||
);
|
||||
assert_forbidden(
|
||||
bill_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.email_query(None::<Filter>, None::<Vec<_>>)
|
||||
.await,
|
||||
);
|
||||
jane_client
|
||||
.mailbox_update_acl(
|
||||
&inbox_id,
|
||||
&john_id.to_string(),
|
||||
john.id_string(),
|
||||
[
|
||||
ACL::ReadItems,
|
||||
ACL::AddItems,
|
||||
@@ -572,7 +525,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.mailbox_get(&inbox_id, [mailbox::Property::MyRights].into())
|
||||
.await
|
||||
.unwrap()
|
||||
@@ -591,13 +544,13 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
]
|
||||
);
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.mailbox_update_acl(&inbox_id, &bill_id.to_string(), [ACL::ReadItems])
|
||||
.set_default_account_id(jane.id_string())
|
||||
.mailbox_update_acl(&inbox_id, bill.id_string(), [ACL::ReadItems])
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
bill_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.email_query(
|
||||
None::<Filter>,
|
||||
vec![email::query::Comparator::subject()].into()
|
||||
@@ -613,12 +566,12 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
|
||||
// Revoke all access to John
|
||||
jane_client
|
||||
.mailbox_update_acl(&inbox_id, &john_id.to_string(), [])
|
||||
.mailbox_update_acl(&inbox_id, john.id_string(), [])
|
||||
.await
|
||||
.unwrap();
|
||||
assert_forbidden(
|
||||
john_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.email_get(
|
||||
email_ids.get("jane").unwrap().first().unwrap(),
|
||||
[Property::Subject].into(),
|
||||
@@ -626,15 +579,10 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.await,
|
||||
);
|
||||
john_client.refresh_session().await.unwrap();
|
||||
assert!(
|
||||
john_client
|
||||
.session()
|
||||
.account(&jane_id.to_string())
|
||||
.is_none()
|
||||
);
|
||||
assert!(john_client.session().account(jane.id_string()).is_none());
|
||||
assert_eq!(
|
||||
bill_client
|
||||
.set_default_account_id(jane_id.to_string())
|
||||
.set_default_account_id(jane.id_string())
|
||||
.email_get(
|
||||
email_ids.get("jane").unwrap().first().unwrap(),
|
||||
[Property::Subject].into(),
|
||||
@@ -666,7 +614,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
assert_eq!(
|
||||
john_client
|
||||
.session()
|
||||
.account(&sales_id.to_string())
|
||||
.account(sales.id_string())
|
||||
.unwrap()
|
||||
.name(),
|
||||
"sales@example.com"
|
||||
@@ -674,30 +622,25 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
assert!(
|
||||
!john_client
|
||||
.session()
|
||||
.account(&sales_id.to_string())
|
||||
.account(sales.id_string())
|
||||
.unwrap()
|
||||
.is_personal()
|
||||
);
|
||||
assert_eq!(
|
||||
jane_client
|
||||
.session()
|
||||
.account(&sales_id.to_string())
|
||||
.account(sales.id_string())
|
||||
.unwrap()
|
||||
.name(),
|
||||
"sales@example.com"
|
||||
);
|
||||
assert!(
|
||||
bill_client
|
||||
.session()
|
||||
.account(&sales_id.to_string())
|
||||
.is_none()
|
||||
);
|
||||
assert!(bill_client.session().account(sales.id_string()).is_none());
|
||||
|
||||
// Insert a message in Sales's inbox
|
||||
let blob_id = john_client
|
||||
.set_default_account_id(sales_id.to_string())
|
||||
.set_default_account_id(sales.id_string())
|
||||
.upload(
|
||||
Some(&sales_id.to_string()),
|
||||
Some(sales.id_string()),
|
||||
concat!(
|
||||
"From: acl_test@example.com\r\n",
|
||||
"To: sales@example.com\r\n",
|
||||
@@ -729,7 +672,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
// Both Jane and John should be able to see this message, but not Bill
|
||||
assert_eq!(
|
||||
john_client
|
||||
.set_default_account_id(sales_id.to_string())
|
||||
.set_default_account_id(sales.id_string())
|
||||
.email_get(&email_id, [Property::Subject].into(),)
|
||||
.await
|
||||
.unwrap()
|
||||
@@ -740,7 +683,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
);
|
||||
assert_eq!(
|
||||
jane_client
|
||||
.set_default_account_id(sales_id.to_string())
|
||||
.set_default_account_id(sales.id_string())
|
||||
.email_get(&email_id, [Property::Subject].into(),)
|
||||
.await
|
||||
.unwrap()
|
||||
@@ -751,7 +694,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
);
|
||||
assert_forbidden(
|
||||
bill_client
|
||||
.set_default_account_id(sales_id.to_string())
|
||||
.set_default_account_id(sales.id_string())
|
||||
.email_get(&email_id, [Property::Subject].into())
|
||||
.await,
|
||||
);
|
||||
@@ -769,15 +712,14 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.await;
|
||||
assert_forbidden(
|
||||
john_client
|
||||
.set_default_account_id(sales_id.to_string())
|
||||
.set_default_account_id(sales.id_string())
|
||||
.email_get(&email_id, [Property::Subject].into())
|
||||
.await,
|
||||
);
|
||||
|
||||
// Destroy test account data
|
||||
for id in [john_id, bill_id, jane_id, sales_id] {
|
||||
params.client.set_default_account_id(id.to_string());
|
||||
destroy_all_mailboxes(params).await;
|
||||
for id in [john, bill, jane, sales] {
|
||||
params.destroy_all_mailboxes(id).await;
|
||||
}
|
||||
assert_is_empty(server).await;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
println!("Running Email Changes tests...");
|
||||
|
||||
let server = params.server.clone();
|
||||
params.client.set_default_account_id(Id::new(1));
|
||||
let account = params.account("jdoe@example.com");
|
||||
let client = account.client();
|
||||
let mut states = vec![State::Initial];
|
||||
|
||||
for (changes, expected_changelog) in [
|
||||
@@ -133,7 +134,9 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.into_iter()
|
||||
{
|
||||
let mut batch = BatchBuilder::new();
|
||||
batch.with_account_id(1).with_collection(Collection::Email);
|
||||
batch
|
||||
.with_account_id(account.id().document_id())
|
||||
.with_collection(Collection::Email);
|
||||
|
||||
for change in changes {
|
||||
match change {
|
||||
@@ -175,11 +178,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
|
||||
let mut new_state = State::Initial;
|
||||
for (test_num, state) in (states).iter().enumerate() {
|
||||
let changes = params
|
||||
.client
|
||||
.email_changes(state.to_string(), None)
|
||||
.await
|
||||
.unwrap();
|
||||
let changes = client.email_changes(state.to_string(), None).await.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
expected_changelog[test_num],
|
||||
@@ -220,8 +219,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
let mut int_state = state.clone();
|
||||
|
||||
for _ in 0..100 {
|
||||
let changes = params
|
||||
.client
|
||||
let changes = client
|
||||
.email_changes(int_state.to_string(), max_changes.into())
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -300,8 +298,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
states.push(new_state);
|
||||
}
|
||||
|
||||
let changes = params
|
||||
.client
|
||||
let changes = client
|
||||
.email_changes(State::Initial.to_string(), None)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@@ -4,17 +4,18 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use crate::jmap::{JMAPTest, assert_is_empty, mail::mailbox::destroy_all_mailboxes};
|
||||
use crate::jmap::{JMAPTest, assert_is_empty, mail::mailbox::destroy_all_mailboxes_for_account};
|
||||
use jmap_client::mailbox::Role;
|
||||
use types::id::Id;
|
||||
|
||||
pub async fn test(params: &mut JMAPTest) {
|
||||
println!("Running Email Copy tests...");
|
||||
let server = params.server.clone();
|
||||
let account = params.account("admin");
|
||||
let mut client = account.client_owned().await;
|
||||
|
||||
// Create a mailbox on account 1
|
||||
let ac1_mailbox_id = params
|
||||
.client
|
||||
let ac1_mailbox_id = client
|
||||
.set_default_account_id(Id::new(1).to_string())
|
||||
.mailbox_create("Copy Test Ac# 1", None::<String>, Role::None)
|
||||
.await
|
||||
@@ -22,8 +23,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.take_id();
|
||||
|
||||
// Insert a message on account 1
|
||||
let ac1_email_id = params
|
||||
.client
|
||||
let ac1_email_id = client
|
||||
.email_import(
|
||||
concat!(
|
||||
"From: bill@example.com\r\n",
|
||||
@@ -44,8 +44,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.take_id();
|
||||
|
||||
// Create a mailbox on account 2
|
||||
let ac2_mailbox_id = params
|
||||
.client
|
||||
let ac2_mailbox_id = client
|
||||
.set_default_account_id(Id::new(2).to_string())
|
||||
.mailbox_create("Copy Test Ac# 2", None::<String>, Role::None)
|
||||
.await
|
||||
@@ -53,7 +52,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.take_id();
|
||||
|
||||
// Copy the email and delete it from the first account
|
||||
let mut request = params.client.build();
|
||||
let mut request = client.build();
|
||||
request
|
||||
.copy_email(Id::new(1).to_string())
|
||||
.on_success_destroy_original(true)
|
||||
@@ -73,8 +72,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.take_id();
|
||||
|
||||
// Check that the email was copied
|
||||
let email = params
|
||||
.client
|
||||
let email = client
|
||||
.email_get(&ac2_email_id, None::<Vec<_>>)
|
||||
.await
|
||||
.unwrap()
|
||||
@@ -90,8 +88,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
|
||||
// Check that the email was deleted
|
||||
assert!(
|
||||
params
|
||||
.client
|
||||
client
|
||||
.set_default_account_id(Id::new(1).to_string())
|
||||
.email_get(&ac1_email_id, None::<Vec<_>>)
|
||||
.await
|
||||
@@ -100,8 +97,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
);
|
||||
|
||||
// Empty store
|
||||
destroy_all_mailboxes(params).await;
|
||||
params.client.set_default_account_id(Id::new(2).to_string());
|
||||
destroy_all_mailboxes(params).await;
|
||||
destroy_all_mailboxes_for_account(1).await;
|
||||
destroy_all_mailboxes_for_account(2).await;
|
||||
assert_is_empty(server).await;
|
||||
}
|
||||
|
||||
@@ -4,10 +4,7 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
jmap::{JMAPTest, ManagementApi, mail::delivery::SmtpConnection},
|
||||
};
|
||||
use crate::jmap::{JMAPTest, ManagementApi, mail::delivery::SmtpConnection};
|
||||
use email::message::crypto::{
|
||||
Algorithm, EncryptMessage, EncryptionMethod, EncryptionParams, EncryptionType, try_parse_certs,
|
||||
};
|
||||
@@ -17,28 +14,13 @@ use store::{
|
||||
Deserialize, Serialize,
|
||||
write::{Archive, Archiver},
|
||||
};
|
||||
use types::id::Id;
|
||||
|
||||
pub async fn test(params: &mut JMAPTest) {
|
||||
println!("Running Encryption-at-rest tests...");
|
||||
|
||||
// Create test account
|
||||
let server = params.server.clone();
|
||||
let client = &mut params.client;
|
||||
let account_id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com"],
|
||||
)
|
||||
.await,
|
||||
)
|
||||
.to_string();
|
||||
let account = params.account("jdoe@example.com");
|
||||
let client = account.client();
|
||||
|
||||
// Build API
|
||||
let api = ManagementApi::new(8899, "jdoe@example.com", "12345");
|
||||
@@ -143,7 +125,6 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.await;
|
||||
|
||||
// Check messages
|
||||
client.set_default_account_id(&account_id);
|
||||
let mut request = client.build();
|
||||
request.get_email();
|
||||
let emails = request.send_get_email().await.unwrap().take_list();
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
jmap::{JMAPTest, assert_is_empty, mail::mailbox::destroy_all_mailboxes},
|
||||
jmap::{JMAPTest, assert_is_empty},
|
||||
webdav::DummyWebDavClient,
|
||||
};
|
||||
use email::{
|
||||
@@ -14,55 +14,21 @@ use email::{
|
||||
mailbox::{INBOX_ID, JUNK_ID},
|
||||
};
|
||||
use groupware::DavResourceName;
|
||||
use std::{str::FromStr, time::Duration};
|
||||
use std::time::Duration;
|
||||
use tokio::{
|
||||
io::{AsyncBufReadExt, AsyncWriteExt, BufReader, Lines, ReadHalf, WriteHalf},
|
||||
net::TcpStream,
|
||||
};
|
||||
use types::{collection::Collection, id::Id};
|
||||
use types::collection::Collection;
|
||||
|
||||
pub async fn test(params: &mut JMAPTest) {
|
||||
println!("Running message delivery tests...");
|
||||
|
||||
// Create a domain name and a test account
|
||||
let server = params.server.clone();
|
||||
let mut account_id_1 = String::new();
|
||||
let mut account_id_2 = String::new();
|
||||
let mut account_id_3 = String::new();
|
||||
|
||||
for (id, email, password, name, aliases) in [
|
||||
(
|
||||
&mut account_id_1,
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
Some(&["jdoe@example.com", "john.doe@example.com"][..]),
|
||||
),
|
||||
(
|
||||
&mut account_id_2,
|
||||
"jane@example.com",
|
||||
"abcdef",
|
||||
"Jane Smith",
|
||||
None,
|
||||
),
|
||||
(
|
||||
&mut account_id_3,
|
||||
"bill@example.com",
|
||||
"098765",
|
||||
"Bill Foobar",
|
||||
None,
|
||||
),
|
||||
] {
|
||||
*id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.create_test_user(email, password, name, aliases.unwrap_or(&[email][..]))
|
||||
.await,
|
||||
)
|
||||
.to_string();
|
||||
}
|
||||
let john = params.account("jdoe@example.com");
|
||||
let jane = params.account("jane.smith@example.com");
|
||||
let bill = params.account("bill@example.com");
|
||||
|
||||
// Create a mailing list
|
||||
server
|
||||
@@ -72,7 +38,11 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.create_test_list(
|
||||
"members@example.com",
|
||||
"Mailing List",
|
||||
&["jdoe@example.com", "jane@example.com", "bill@example.com"],
|
||||
&[
|
||||
"jdoe@example.com",
|
||||
"jane.smith@example.com",
|
||||
"bill@example.com",
|
||||
],
|
||||
)
|
||||
.await;
|
||||
|
||||
@@ -95,12 +65,14 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
)
|
||||
.await;
|
||||
|
||||
let john_id = Id::from_str(&account_id_1).unwrap().document_id();
|
||||
let john_cache = server.get_cached_messages(john_id).await.unwrap();
|
||||
let john_cache = server
|
||||
.get_cached_messages(john.id().document_id())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
server
|
||||
.get_document_ids(john_id, Collection::Email)
|
||||
.get_document_ids(john.id().document_id(), Collection::Email)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
@@ -126,11 +98,14 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
),
|
||||
)
|
||||
.await;
|
||||
let john_cache = server.get_cached_messages(john_id).await.unwrap();
|
||||
let john_cache = server
|
||||
.get_cached_messages(john.id().document_id())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
server
|
||||
.get_document_ids(john_id, Collection::Email)
|
||||
.get_document_ids(john.id().document_id(), Collection::Email)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
@@ -175,11 +150,14 @@ END:VCARD
|
||||
),
|
||||
)
|
||||
.await;
|
||||
let john_cache = server.get_cached_messages(john_id).await.unwrap();
|
||||
let john_cache = server
|
||||
.get_cached_messages(john.id().document_id())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
server
|
||||
.get_document_ids(john_id, Collection::Email)
|
||||
.get_document_ids(john.id().document_id(), Collection::Email)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
@@ -194,7 +172,7 @@ END:VCARD
|
||||
lmtp.expn("members@example.com", 2)
|
||||
.await
|
||||
.assert_contains("jdoe@example.com")
|
||||
.assert_contains("jane@example.com")
|
||||
.assert_contains("jane.smith@example.com")
|
||||
.assert_contains("bill@example.com");
|
||||
lmtp.expn("non_existant@example.com", 5).await;
|
||||
lmtp.expn("jdoe@example.com", 5).await;
|
||||
@@ -217,20 +195,17 @@ END:VCARD
|
||||
)
|
||||
.await;
|
||||
|
||||
for (account_id, num_messages) in [(&account_id_1, 4), (&account_id_2, 1), (&account_id_3, 1)] {
|
||||
for (account, num_messages) in [(john, 4), (jane, 1), (bill, 1)] {
|
||||
assert_eq!(
|
||||
server
|
||||
.get_document_ids(
|
||||
Id::from_str(account_id).unwrap().document_id(),
|
||||
Collection::Email
|
||||
)
|
||||
.get_document_ids(account.id().document_id(), Collection::Email)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
.len(),
|
||||
num_messages,
|
||||
"for {}",
|
||||
account_id
|
||||
account.id_string()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -257,20 +232,17 @@ END:VCARD
|
||||
)
|
||||
.await;
|
||||
|
||||
for (account_id, num_messages) in [(&account_id_1, 4), (&account_id_2, 2), (&account_id_3, 2)] {
|
||||
for (account, num_messages) in [(john, 4), (jane, 2), (bill, 2)] {
|
||||
assert_eq!(
|
||||
server
|
||||
.get_document_ids(
|
||||
Id::from_str(account_id).unwrap().document_id(),
|
||||
Collection::Email
|
||||
)
|
||||
.get_document_ids(account.id().document_id(), Collection::Email)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
.len(),
|
||||
num_messages,
|
||||
"for {}",
|
||||
account_id
|
||||
account.id_string()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -281,7 +253,7 @@ END:VCARD
|
||||
"members@example.com",
|
||||
"jdoe@example.com",
|
||||
"john.doe@example.com",
|
||||
"jane@example.com",
|
||||
"jane.smith@example.com",
|
||||
"bill@example.com",
|
||||
],
|
||||
concat!(
|
||||
@@ -295,27 +267,23 @@ END:VCARD
|
||||
)
|
||||
.await;
|
||||
|
||||
for (account_id, num_messages) in [(&account_id_1, 5), (&account_id_2, 3), (&account_id_3, 3)] {
|
||||
for (account, num_messages) in [(john, 5), (jane, 3), (bill, 3)] {
|
||||
assert_eq!(
|
||||
server
|
||||
.get_document_ids(
|
||||
Id::from_str(account_id).unwrap().document_id(),
|
||||
Collection::Email
|
||||
)
|
||||
.get_document_ids(account.id().document_id(), Collection::Email)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
.len(),
|
||||
num_messages,
|
||||
"for {}",
|
||||
account_id
|
||||
account.id_string()
|
||||
);
|
||||
}
|
||||
|
||||
// Remove test data
|
||||
for account_id in [&account_id_1, &account_id_2, &account_id_3] {
|
||||
params.client.set_default_account_id(account_id);
|
||||
destroy_all_mailboxes(params).await;
|
||||
for account in [john, jane, bill] {
|
||||
params.destroy_all_mailboxes(account).await;
|
||||
}
|
||||
assert_is_empty(server).await;
|
||||
|
||||
|
||||
@@ -4,9 +4,7 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use crate::jmap::{
|
||||
JMAPTest, assert_is_empty, mail::mailbox::destroy_all_mailboxes, replace_blob_ids,
|
||||
};
|
||||
use crate::jmap::{JMAPTest, assert_is_empty, replace_blob_ids};
|
||||
use ::email::mailbox::INBOX_ID;
|
||||
use jmap_client::email::{self, Header, HeaderForm, import::EmailImportResponse};
|
||||
use mail_parser::HeaderName;
|
||||
@@ -23,7 +21,8 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
test_dir.push("email_get");
|
||||
|
||||
let mailbox_id = Id::from(INBOX_ID).to_string();
|
||||
params.client.set_default_account_id(Id::from(1u64));
|
||||
let account = params.account("jdoe@example.com");
|
||||
let client = account.client();
|
||||
|
||||
for file_name in fs::read_dir(&test_dir).unwrap() {
|
||||
let mut file_name = file_name.as_ref().unwrap().path();
|
||||
@@ -36,13 +35,11 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
let blob_len = blob.len();
|
||||
|
||||
// Import email
|
||||
let mut request = params.client.build();
|
||||
let mut request = client.build();
|
||||
let import_request = request
|
||||
.import_email()
|
||||
.account_id(Id::from(1u64).to_string())
|
||||
.email(
|
||||
params
|
||||
.client
|
||||
client
|
||||
.upload(None, blob, None)
|
||||
.await
|
||||
.unwrap()
|
||||
@@ -56,7 +53,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
assert_ne!(response.old_state(), Some(response.new_state()));
|
||||
let email = response.created(&id).unwrap();
|
||||
|
||||
let mut request = params.client.build();
|
||||
let mut request = client.build();
|
||||
request
|
||||
.get_email()
|
||||
.ids([email.id().unwrap()])
|
||||
@@ -139,7 +136,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
|
||||
if is_headers_test {
|
||||
for property in all_headers() {
|
||||
let mut request = params.client.build();
|
||||
let mut request = client.build();
|
||||
request
|
||||
.get_email()
|
||||
.ids([email.id().unwrap()])
|
||||
@@ -169,7 +166,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
}
|
||||
}
|
||||
|
||||
destroy_all_mailboxes(params).await;
|
||||
params.destroy_all_mailboxes(account).await;
|
||||
assert_is_empty(server).await;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use crate::jmap::{JMAPTest, assert_is_empty, wait_for_index};
|
||||
use crate::jmap::{Account, JMAPTest, assert_is_empty, wait_for_index};
|
||||
use jmap_client::{
|
||||
Error, Set,
|
||||
client::{Client, Credentials},
|
||||
@@ -23,11 +23,12 @@ use types::id::Id;
|
||||
pub async fn test(params: &mut JMAPTest) {
|
||||
println!("Running Mailbox tests...");
|
||||
let server = params.server.clone();
|
||||
let client = &mut params.client;
|
||||
let account = params.account("admin");
|
||||
let mut client = account.client_owned().await;
|
||||
|
||||
// Create test mailboxes
|
||||
client.set_default_account_id(Id::from(0u64));
|
||||
let id_map = create_test_mailboxes(client).await;
|
||||
let id_map = create_test_mailboxes(&client).await;
|
||||
|
||||
// Sort by name
|
||||
assert_eq!(
|
||||
@@ -607,12 +608,11 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
["inbox", "sent", "spam"]
|
||||
);
|
||||
|
||||
destroy_all_mailboxes(params).await;
|
||||
params.client.set_default_account_id(Id::from(1u64));
|
||||
destroy_all_mailboxes_no_wait(&client).await;
|
||||
assert_is_empty(server).await;
|
||||
}
|
||||
|
||||
async fn create_test_mailboxes(client: &mut Client) -> AHashMap<String, String> {
|
||||
async fn create_test_mailboxes(client: &Client) -> AHashMap<String, String> {
|
||||
let mut mailbox_map = AHashMap::default();
|
||||
let mut request = client.build();
|
||||
build_create_query(
|
||||
@@ -657,6 +657,13 @@ fn build_create_query(
|
||||
}
|
||||
}
|
||||
|
||||
impl JMAPTest {
|
||||
pub async fn destroy_all_mailboxes(&self, account: &Account) {
|
||||
wait_for_index(&self.server).await;
|
||||
destroy_all_mailboxes_no_wait(account.client()).await;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn destroy_all_mailboxes_for_account(account_id: u32) {
|
||||
let mut client = Client::new()
|
||||
.credentials(Credentials::basic("admin", "secret"))
|
||||
@@ -670,11 +677,6 @@ pub async fn destroy_all_mailboxes_for_account(account_id: u32) {
|
||||
destroy_all_mailboxes_no_wait(&client).await;
|
||||
}
|
||||
|
||||
pub async fn destroy_all_mailboxes(test: &JMAPTest) {
|
||||
wait_for_index(&test.server).await;
|
||||
destroy_all_mailboxes_no_wait(&test.client).await;
|
||||
}
|
||||
|
||||
pub async fn destroy_all_mailboxes_no_wait(client: &Client) {
|
||||
let mut request = client.build();
|
||||
request.query_mailbox().arguments().sort_as_tree(true);
|
||||
|
||||
@@ -4,30 +4,25 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use crate::jmap::{
|
||||
JMAPTest, assert_is_empty,
|
||||
mail::{get::all_headers, mailbox::destroy_all_mailboxes},
|
||||
replace_blob_ids,
|
||||
};
|
||||
use crate::jmap::{JMAPTest, assert_is_empty, mail::get::all_headers, replace_blob_ids};
|
||||
use jmap_client::{
|
||||
email::{self, Header, HeaderForm},
|
||||
mailbox::Role,
|
||||
};
|
||||
use std::{fs, path::PathBuf};
|
||||
use types::id::Id;
|
||||
|
||||
pub async fn test(params: &mut JMAPTest) {
|
||||
println!("Running Email Parse tests...");
|
||||
let server = params.server.clone();
|
||||
let account = params.account("jdoe@example.com");
|
||||
let client = account.client();
|
||||
|
||||
let mut test_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
test_dir.push("resources");
|
||||
test_dir.push("jmap");
|
||||
test_dir.push("email_parse");
|
||||
|
||||
let mailbox_id = params
|
||||
.client
|
||||
.set_default_account_id(Id::new(1).to_string())
|
||||
let mailbox_id = client
|
||||
.mailbox_create("JMAP Parse", None::<String>, Role::None)
|
||||
.await
|
||||
.unwrap()
|
||||
@@ -38,8 +33,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
let mut test_file = test_dir.clone();
|
||||
test_file.push(test_name);
|
||||
|
||||
let email = params
|
||||
.client
|
||||
let email = client
|
||||
.email_import(
|
||||
fs::read(&test_file).unwrap(),
|
||||
[mailbox_id.clone()],
|
||||
@@ -49,8 +43,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let blob_id = params
|
||||
.client
|
||||
let blob_id = client
|
||||
.email_get(email.id().unwrap(), Some([email::Property::Attachments]))
|
||||
.await
|
||||
.unwrap()
|
||||
@@ -63,8 +56,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.unwrap()
|
||||
.to_string();
|
||||
|
||||
let email = params
|
||||
.client
|
||||
let email = client
|
||||
.email_parse(
|
||||
&blob_id,
|
||||
[
|
||||
@@ -123,7 +115,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
for part in parts {
|
||||
let blob_id = part.blob_id().unwrap();
|
||||
|
||||
let inner_blob = params.client.download(blob_id).await.unwrap();
|
||||
let inner_blob = client.download(blob_id).await.unwrap();
|
||||
|
||||
test_file.set_extension(format!("part{}", part.part_id().unwrap()));
|
||||
|
||||
@@ -154,15 +146,13 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
// Test header parsing on a temporary blob
|
||||
let mut test_file = test_dir;
|
||||
test_file.push("headers.eml");
|
||||
let blob_id = params
|
||||
.client
|
||||
let blob_id = client
|
||||
.upload(None, fs::read(&test_file).unwrap(), None)
|
||||
.await
|
||||
.unwrap()
|
||||
.take_blob_id();
|
||||
|
||||
let mut email = params
|
||||
.client
|
||||
let mut email = client
|
||||
.email_parse(
|
||||
&blob_id,
|
||||
[
|
||||
@@ -213,8 +203,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
|
||||
for property in all_headers() {
|
||||
email.headers.extend(
|
||||
params
|
||||
.client
|
||||
client
|
||||
.email_parse(&blob_id, [property].into(), [].into(), None)
|
||||
.await
|
||||
.unwrap()
|
||||
@@ -233,6 +222,6 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
panic!("Test failed, output saved to {}", test_file.display());
|
||||
}
|
||||
|
||||
destroy_all_mailboxes(params).await;
|
||||
params.destroy_all_mailboxes(account).await;
|
||||
assert_is_empty(server).await;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
use crate::{
|
||||
jmap::{JMAPTest, assert_is_empty, mail::mailbox::destroy_all_mailboxes, wait_for_index},
|
||||
jmap::{JMAPTest, assert_is_empty, wait_for_index},
|
||||
store::{deflate_test_resource, query::FIELDS},
|
||||
};
|
||||
use ::email::{cache::MessageCacheFetch, mailbox::Mailbox};
|
||||
@@ -31,8 +31,9 @@ const MAX_MESSAGES_PER_THREAD: usize = 100;
|
||||
pub async fn test(params: &mut JMAPTest, insert: bool) {
|
||||
println!("Running Email Query tests...");
|
||||
let server = params.server.clone();
|
||||
let client = &mut params.client;
|
||||
client.set_default_account_id(Id::new(1));
|
||||
let account = params.account("jdoe@example.com");
|
||||
let client = account.client();
|
||||
|
||||
if insert {
|
||||
// Add some "virtual" mailbox ids so create doesn't fail
|
||||
let mut batch = BatchBuilder::new();
|
||||
@@ -105,11 +106,11 @@ pub async fn test(params: &mut JMAPTest, insert: bool) {
|
||||
.unwrap_set_email()
|
||||
.unwrap();
|
||||
|
||||
destroy_all_mailboxes(params).await;
|
||||
params.destroy_all_mailboxes(account).await;
|
||||
assert_is_empty(server).await;
|
||||
}
|
||||
|
||||
pub async fn query(client: &mut Client) {
|
||||
pub async fn query(client: &Client) {
|
||||
for (filter, sort, expected_results) in [
|
||||
(
|
||||
Filter::and(vec![
|
||||
@@ -403,7 +404,7 @@ pub async fn query(client: &mut Client) {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn query_options(client: &mut Client) {
|
||||
pub async fn query_options(client: &Client) {
|
||||
for (query, expected_results, expected_results_collapsed) in [
|
||||
(
|
||||
EmailQuery {
|
||||
@@ -698,7 +699,7 @@ pub async fn query_options(client: &mut Client) {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn create(client: &mut Client) {
|
||||
pub async fn create(client: &Client) {
|
||||
let sent_at = now();
|
||||
let now = Instant::now();
|
||||
let mut fields = AHashMap::default();
|
||||
@@ -838,7 +839,7 @@ pub async fn create(client: &mut Client) {
|
||||
);
|
||||
}
|
||||
|
||||
async fn get_anchor(client: &mut Client, anchor: &str) -> Option<String> {
|
||||
async fn get_anchor(client: &Client, anchor: &str) -> Option<String> {
|
||||
client
|
||||
.email_query(
|
||||
email::query::Filter::header("Message-Id", anchor.into()).into(),
|
||||
|
||||
@@ -6,10 +6,7 @@
|
||||
|
||||
use crate::jmap::{
|
||||
JMAPTest, assert_is_empty,
|
||||
mail::{
|
||||
changes::{LogAction, ParseState},
|
||||
mailbox::destroy_all_mailboxes,
|
||||
},
|
||||
mail::changes::{LogAction, ParseState},
|
||||
};
|
||||
use ::email::message::metadata::MessageData;
|
||||
use common::storage::index::ObjectIndexBuilder;
|
||||
@@ -32,15 +29,15 @@ use types::{
|
||||
pub async fn test(params: &mut JMAPTest) {
|
||||
println!("Running Email QueryChanges tests...");
|
||||
let server = params.server.clone();
|
||||
let mailbox1_id = params
|
||||
.client
|
||||
.set_default_account_id(Id::new(1).to_string())
|
||||
let account = params.account("jdoe@example.com");
|
||||
let client = account.client();
|
||||
|
||||
let mailbox1_id = client
|
||||
.mailbox_create("JMAP Changes 1", None::<String>, Role::None)
|
||||
.await
|
||||
.unwrap()
|
||||
.take_id();
|
||||
let mailbox2_id = params
|
||||
.client
|
||||
let mailbox2_id = client
|
||||
.mailbox_create("JMAP Changes 2", None::<String>, Role::None)
|
||||
.await
|
||||
.unwrap()
|
||||
@@ -91,8 +88,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
match &change {
|
||||
LogAction::Insert(id) => {
|
||||
let jmap_id = Id::from_str(
|
||||
params
|
||||
.client
|
||||
client
|
||||
.email_import(
|
||||
format!(
|
||||
"From: test_{}\nSubject: test_{}\n\ntest",
|
||||
@@ -131,7 +127,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
}
|
||||
LogAction::Delete(id) => {
|
||||
let id = *id_map.get(id).unwrap();
|
||||
params.client.email_destroy(&id.to_string()).await.unwrap();
|
||||
client.email_destroy(&id.to_string()).await.unwrap();
|
||||
removed_ids.insert(id);
|
||||
}
|
||||
LogAction::Move(from, to) => {
|
||||
@@ -141,7 +137,11 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
//let new_thread_id = store::rand::random::<u32>();
|
||||
|
||||
let old_message_ = server
|
||||
.get_archive(1, Collection::Email, id.document_id())
|
||||
.get_archive(
|
||||
account.id().document_id(),
|
||||
Collection::Email,
|
||||
id.document_id(),
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
@@ -155,7 +155,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.data
|
||||
.write(
|
||||
BatchBuilder::new()
|
||||
.with_account_id(1)
|
||||
.with_account_id(account.id().document_id())
|
||||
.with_collection(Collection::Email)
|
||||
.update_document(id.document_id())
|
||||
.custom(
|
||||
@@ -220,7 +220,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
if test_num == 3 && query.up_to_id.is_none() {
|
||||
continue;
|
||||
}
|
||||
let mut request = params.client.build();
|
||||
let mut request = client.build();
|
||||
let query_request = request
|
||||
.query_email_changes(query.since_query_state.to_string())
|
||||
.sort(query.sort);
|
||||
@@ -276,7 +276,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
states.push(new_state);
|
||||
}
|
||||
|
||||
destroy_all_mailboxes(params).await;
|
||||
params.destroy_all_mailboxes(account).await;
|
||||
assert_is_empty(server).await;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,9 +4,7 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use crate::jmap::{
|
||||
JMAPTest, assert_is_empty, mail::mailbox::destroy_all_mailboxes, wait_for_index,
|
||||
};
|
||||
use crate::jmap::{JMAPTest, assert_is_empty, wait_for_index};
|
||||
use email::mailbox::INBOX_ID;
|
||||
use jmap_client::{core::query, email::query::Filter};
|
||||
use std::{fs, path::PathBuf};
|
||||
@@ -16,9 +14,9 @@ use types::id::Id;
|
||||
pub async fn test(params: &mut JMAPTest) {
|
||||
println!("Running SearchSnippet tests...");
|
||||
let server = params.server.clone();
|
||||
|
||||
let account = params.account("jdoe@example.com");
|
||||
let client = account.client();
|
||||
let mailbox_id = Id::from(INBOX_ID).to_string();
|
||||
params.client.set_default_account_id(Id::from(1u64));
|
||||
|
||||
let mut email_ids = AHashMap::default();
|
||||
|
||||
@@ -37,8 +35,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
] {
|
||||
let mut file_name = test_dir.clone();
|
||||
file_name.push(format!("{}.eml", email_name));
|
||||
let email_id = params
|
||||
.client
|
||||
let email_id = client
|
||||
.email_import(
|
||||
fs::read(&file_name).unwrap(),
|
||||
[&mailbox_id],
|
||||
@@ -135,7 +132,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
)),
|
||||
),
|
||||
] {
|
||||
let mut request = params.client.build();
|
||||
let mut request = client.build();
|
||||
let result_ref = request
|
||||
.query_email()
|
||||
.filter(filter.clone())
|
||||
@@ -166,6 +163,6 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
}
|
||||
|
||||
// Destroy test data
|
||||
destroy_all_mailboxes(params).await;
|
||||
params.destroy_all_mailboxes(account).await;
|
||||
assert_is_empty(server).await;
|
||||
}
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
*/
|
||||
|
||||
use crate::jmap::{
|
||||
JMAPTest, assert_is_empty, find_values, mail::mailbox::destroy_all_mailboxes, replace_blob_ids,
|
||||
replace_boundaries, replace_values,
|
||||
JMAPTest, assert_is_empty, find_values, replace_blob_ids, replace_boundaries, replace_values,
|
||||
};
|
||||
use ::email::mailbox::INBOX_ID;
|
||||
use ahash::AHashSet;
|
||||
@@ -23,18 +22,18 @@ use types::id::Id;
|
||||
pub async fn test(params: &mut JMAPTest) {
|
||||
println!("Running Email Set tests...");
|
||||
let server = params.server.clone();
|
||||
|
||||
let account = params.account("jdoe@example.com");
|
||||
let client = account.client();
|
||||
let mailbox_id = Id::from(INBOX_ID).to_string();
|
||||
params.client.set_default_account_id(Id::from(1u64));
|
||||
|
||||
create(&mut params.client, &mailbox_id).await;
|
||||
update(&mut params.client, &mailbox_id).await;
|
||||
create(client, &mailbox_id).await;
|
||||
update(client, &mailbox_id).await;
|
||||
|
||||
destroy_all_mailboxes(params).await;
|
||||
params.destroy_all_mailboxes(account).await;
|
||||
assert_is_empty(server).await;
|
||||
}
|
||||
|
||||
async fn create(client: &mut Client, mailbox_id: &str) {
|
||||
async fn create(client: &Client, mailbox_id: &str) {
|
||||
let mut test_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
test_dir.push("resources");
|
||||
test_dir.push("jmap");
|
||||
@@ -162,7 +161,7 @@ async fn create(client: &mut Client, mailbox_id: &str) {
|
||||
}
|
||||
}
|
||||
|
||||
async fn update(client: &mut Client, root_mailbox_id: &str) {
|
||||
async fn update(client: &Client, root_mailbox_id: &str) {
|
||||
// Obtain all messageIds previously created
|
||||
let mailbox = client
|
||||
.email_query(
|
||||
@@ -174,13 +173,11 @@ async fn update(client: &mut Client, root_mailbox_id: &str) {
|
||||
|
||||
// Create two test mailboxes
|
||||
let test_mailbox1_id = client
|
||||
.set_default_account_id(Id::new(1).to_string())
|
||||
.mailbox_create("Test 1", None::<String>, Role::None)
|
||||
.await
|
||||
.unwrap()
|
||||
.take_id();
|
||||
let test_mailbox2_id = client
|
||||
.set_default_account_id(Id::new(1).to_string())
|
||||
.mailbox_create("Test 2", None::<String>, Role::None)
|
||||
.await
|
||||
.unwrap()
|
||||
@@ -296,7 +293,7 @@ async fn update(client: &mut Client, root_mailbox_id: &str) {
|
||||
}
|
||||
|
||||
pub async fn assert_email_properties(
|
||||
client: &mut Client,
|
||||
client: &Client,
|
||||
message_id: &str,
|
||||
mailbox_ids: &[&str],
|
||||
keywords: &[&str],
|
||||
|
||||
@@ -5,12 +5,10 @@
|
||||
*/
|
||||
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
jmap::{
|
||||
JMAPTest, assert_is_empty,
|
||||
mail::{
|
||||
delivery::SmtpConnection,
|
||||
mailbox::destroy_all_mailboxes,
|
||||
submission::{MockMessage, assert_message_delivery, spawn_mock_smtp_server},
|
||||
},
|
||||
},
|
||||
@@ -27,29 +25,12 @@ use std::{
|
||||
path::PathBuf,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use types::id::Id;
|
||||
|
||||
pub async fn test(params: &mut JMAPTest) {
|
||||
println!("Running Sieve tests...");
|
||||
let server = params.server.clone();
|
||||
let client = &mut params.client;
|
||||
|
||||
// Create test account
|
||||
let account_id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com"],
|
||||
)
|
||||
.await,
|
||||
)
|
||||
.to_string();
|
||||
client.set_default_account_id(&account_id);
|
||||
let account = params.account("jdoe@example.com");
|
||||
let client = account.client();
|
||||
|
||||
// Validate scripts
|
||||
client
|
||||
@@ -515,7 +496,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
for id in request.send_query_sieve_script().await.unwrap().take_ids() {
|
||||
client.sieve_script_destroy(&id).await.unwrap();
|
||||
}
|
||||
destroy_all_mailboxes(params).await;
|
||||
params.destroy_all_mailboxes(account).await;
|
||||
assert_is_empty(server).await;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,11 +5,7 @@
|
||||
*/
|
||||
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
jmap::{
|
||||
JMAPTest, assert_is_empty,
|
||||
mail::{mailbox::destroy_all_mailboxes, set::assert_email_properties},
|
||||
},
|
||||
jmap::{JMAPTest, assert_is_empty, mail::set::assert_email_properties},
|
||||
smtp::DnsCache,
|
||||
};
|
||||
use ahash::AHashMap;
|
||||
@@ -66,7 +62,8 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
println!("Running E-mail submissions tests...");
|
||||
// Start mock SMTP server
|
||||
let server = params.server.clone();
|
||||
let client = &mut params.client;
|
||||
let account = params.account("jdoe@example.com");
|
||||
let client = account.client();
|
||||
let (mut smtp_rx, smtp_settings) = spawn_mock_smtp_server();
|
||||
server.ipv4_add(
|
||||
"localhost",
|
||||
@@ -74,25 +71,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
Instant::now() + std::time::Duration::from_secs(10),
|
||||
);
|
||||
|
||||
// Create a test account
|
||||
let server = params.server.clone();
|
||||
let account_id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com", "john.doe@example.com"],
|
||||
)
|
||||
.await,
|
||||
)
|
||||
.to_string();
|
||||
|
||||
// Test automatic identity creation
|
||||
client.set_default_account_id(&account_id);
|
||||
for (identity_id, email) in [(2u64, "jdoe@example.com"), (1u64, "john.doe@example.com")] {
|
||||
let identity = client
|
||||
.identity_get(&Id::from(identity_id).to_string(), None)
|
||||
@@ -497,7 +476,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.await;
|
||||
client.email_submission_destroy(&id).await.unwrap();
|
||||
}
|
||||
destroy_all_mailboxes(params).await;
|
||||
params.destroy_all_mailboxes(account).await;
|
||||
assert_is_empty(server).await;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,17 +4,16 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use crate::jmap::{JMAPTest, assert_is_empty, mail::mailbox::destroy_all_mailboxes};
|
||||
use crate::jmap::{JMAPTest, assert_is_empty};
|
||||
use jmap_client::mailbox::Role;
|
||||
use types::id::Id;
|
||||
|
||||
pub async fn test(params: &mut JMAPTest) {
|
||||
println!("Running Email Thread tests...");
|
||||
let server = params.server.clone();
|
||||
let account = params.account("jdoe@example.com");
|
||||
let client = account.client();
|
||||
|
||||
let mailbox_id = params
|
||||
.client
|
||||
.set_default_account_id(Id::new(1).to_string())
|
||||
let mailbox_id = client
|
||||
.mailbox_create("JMAP Get", None::<String>, Role::None)
|
||||
.await
|
||||
.unwrap()
|
||||
@@ -24,8 +23,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
let mut thread_id = "".to_string();
|
||||
|
||||
for num in [5, 3, 1, 2, 4] {
|
||||
let mut email = params
|
||||
.client
|
||||
let mut email = client
|
||||
.email_import(
|
||||
format!("Subject: test\nReferences: <1234>\n\n{}", num).into_bytes(),
|
||||
[&mailbox_id],
|
||||
@@ -39,8 +37,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
params
|
||||
.client
|
||||
client
|
||||
.thread_get(&thread_id)
|
||||
.await
|
||||
.unwrap()
|
||||
@@ -49,6 +46,6 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
expected_result
|
||||
);
|
||||
|
||||
destroy_all_mailboxes(params).await;
|
||||
params.destroy_all_mailboxes(account).await;
|
||||
assert_is_empty(server).await;
|
||||
}
|
||||
|
||||
@@ -5,10 +5,13 @@
|
||||
*/
|
||||
|
||||
use crate::{
|
||||
jmap::{JMAPTest, assert_is_empty, mail::mailbox::destroy_all_mailboxes},
|
||||
jmap::{JMAPTest, assert_is_empty, mail::mailbox::destroy_all_mailboxes_no_wait},
|
||||
store::deflate_test_resource,
|
||||
};
|
||||
use ::email::message::ingest::{EmailIngest, IngestEmail, IngestSource};
|
||||
use ::email::{
|
||||
mailbox::INBOX_ID,
|
||||
message::ingest::{EmailIngest, IngestEmail, IngestSource},
|
||||
};
|
||||
use common::auth::AccessToken;
|
||||
use jmap_client::{email, mailbox::Role};
|
||||
use mail_parser::{MessageParser, mailbox::mbox::MessageIterator};
|
||||
@@ -27,7 +30,8 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
async fn test_single_thread(params: &mut JMAPTest) {
|
||||
println!("Running Email Merge Threads tests...");
|
||||
let server = params.server.clone();
|
||||
let client = &mut params.client;
|
||||
let account = params.account("admin");
|
||||
let mut client = account.client_owned().await;
|
||||
let mut all_mailboxes = AHashMap::default();
|
||||
|
||||
for (base_test_num, test) in [test_1(), test_2(), test_3()].iter().enumerate() {
|
||||
@@ -195,10 +199,8 @@ async fn test_single_thread(params: &mut JMAPTest) {
|
||||
// Delete all messages and make sure no keys are left in the store.
|
||||
for (base_test_num, mailbox_ids) in all_mailboxes {
|
||||
for (test_num, _) in mailbox_ids.into_iter().enumerate() {
|
||||
params
|
||||
.client
|
||||
.set_default_account_id(Id::new((base_test_num + test_num) as u64).to_string());
|
||||
destroy_all_mailboxes(params).await;
|
||||
client.set_default_account_id(Id::new((base_test_num + test_num) as u64).to_string());
|
||||
destroy_all_mailboxes_no_wait(&client).await;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,38 +210,25 @@ async fn test_single_thread(params: &mut JMAPTest) {
|
||||
#[allow(dead_code)]
|
||||
async fn test_multi_thread(params: &mut JMAPTest) {
|
||||
println!("Running Email Merge Threads tests (multi-threaded)...");
|
||||
//let semaphore = sync::Arc::Arc::new(tokio::sync::Semaphore::new(100));
|
||||
let mut handles = vec![];
|
||||
|
||||
let mailbox_id = Id::from_str(
|
||||
params
|
||||
.client
|
||||
.set_default_account_id(Id::new(0u64).to_string())
|
||||
.mailbox_create("Inbox", None::<String>, Role::None)
|
||||
.await
|
||||
.unwrap()
|
||||
.id()
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap()
|
||||
.document_id();
|
||||
let account = params.account("jdoe@example.com");
|
||||
let account_id = account.id().document_id();
|
||||
let mailbox_id = INBOX_ID;
|
||||
|
||||
for message in MessageIterator::new(Cursor::new(deflate_test_resource("mailbox.gz")))
|
||||
.collect::<Vec<_>>()
|
||||
.into_iter()
|
||||
{
|
||||
//let permit = Arc::clone(&semaphore);
|
||||
let message = message.unwrap();
|
||||
let server = params.server.clone();
|
||||
handles.push(tokio::task::spawn(async move {
|
||||
//let _permit = permit.acquire().await.expect("Failed to acquire permit");
|
||||
let mut retry_count = 0;
|
||||
loop {
|
||||
match server
|
||||
.email_ingest(IngestEmail {
|
||||
raw_message: message.contents(),
|
||||
message: MessageParser::new().parse(message.contents()),
|
||||
access_token: &AccessToken::from_id(0),
|
||||
access_token: &AccessToken::from_id(account_id),
|
||||
mailbox_ids: vec![mailbox_id],
|
||||
keywords: vec![],
|
||||
received_at: None,
|
||||
@@ -278,14 +267,14 @@ async fn test_multi_thread(params: &mut JMAPTest) {
|
||||
messages as u64,
|
||||
params
|
||||
.server
|
||||
.get_document_ids(0, Collection::Email)
|
||||
.get_document_ids(account_id, Collection::Email)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
.len()
|
||||
);
|
||||
println!("Deleting all messages...");
|
||||
destroy_all_mailboxes(params).await;
|
||||
params.destroy_all_mailboxes(account).await;
|
||||
assert_is_empty(params.server.clone()).await;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,12 +5,10 @@
|
||||
*/
|
||||
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
jmap::{
|
||||
JMAPTest, assert_is_empty,
|
||||
mail::{
|
||||
delivery::SmtpConnection,
|
||||
mailbox::destroy_all_mailboxes,
|
||||
submission::{
|
||||
MockMessage, assert_message_delivery, expect_nothing, spawn_mock_smtp_server,
|
||||
},
|
||||
@@ -20,29 +18,14 @@ use crate::{
|
||||
};
|
||||
use chrono::{TimeDelta, Utc};
|
||||
use std::time::Instant;
|
||||
use types::id::Id;
|
||||
|
||||
pub async fn test(params: &mut JMAPTest) {
|
||||
println!("Running Vacation Response tests...");
|
||||
|
||||
// Create test account
|
||||
let server = params.server.clone();
|
||||
let client = &mut params.client;
|
||||
let account_id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com"],
|
||||
)
|
||||
.await,
|
||||
)
|
||||
.to_string();
|
||||
client.set_default_account_id(&account_id);
|
||||
let account = params.account("jdoe@example.com");
|
||||
let client = account.client();
|
||||
|
||||
// Start mock SMTP server
|
||||
let (mut smtp_rx, smtp_settings) = spawn_mock_smtp_server();
|
||||
@@ -54,7 +37,6 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
|
||||
// Let people know that we'll be down in Kokomo
|
||||
client
|
||||
.set_default_account_id(&account_id)
|
||||
.vacation_response_create(
|
||||
"Off the Florida Keys there's a place called Kokomo",
|
||||
"That's where you wanna go to get away from it all".into(),
|
||||
@@ -179,6 +161,6 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
|
||||
// Remove test data
|
||||
client.vacation_response_destroy().await.unwrap();
|
||||
destroy_all_mailboxes(params).await;
|
||||
params.destroy_all_mailboxes(account).await;
|
||||
assert_is_empty(server).await;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ use crate::{
|
||||
},
|
||||
store::TempDir,
|
||||
};
|
||||
use ahash::AHashMap;
|
||||
use base64::{
|
||||
Engine,
|
||||
engine::general_purpose::{self, STANDARD},
|
||||
@@ -40,9 +41,15 @@ use managesieve::core::ManageSieveSessionManager;
|
||||
use pop3::Pop3SessionManager;
|
||||
use reqwest::header;
|
||||
use serde::{Deserialize, Serialize, de::DeserializeOwned};
|
||||
use serde_json::{Value, json};
|
||||
use services::SpawnServices;
|
||||
use smtp::{SpawnQueueManager, core::SmtpSessionManager};
|
||||
use std::{fmt::Debug, path::PathBuf, sync::Arc, time::Duration};
|
||||
use std::{
|
||||
fmt::{Debug, Display},
|
||||
path::PathBuf,
|
||||
sync::Arc,
|
||||
time::Duration,
|
||||
};
|
||||
use store::{
|
||||
IterateParams, SUBSPACE_PROPERTY, Stores, ValueKey,
|
||||
roaring::RoaringBitmap,
|
||||
@@ -83,7 +90,7 @@ async fn jmap_tests() {
|
||||
mail::thread_merge::test(&mut params).await;
|
||||
mail::mailbox::test(&mut params).await;
|
||||
mail::delivery::test(&mut params).await;
|
||||
mail::acl::test(&mut params).await;*/
|
||||
mail::acl::test(&mut params).await;
|
||||
auth::limits::test(&mut params).await;
|
||||
auth::oauth::test(&mut params).await;
|
||||
core::event_source::test(&mut params).await;
|
||||
@@ -93,7 +100,7 @@ async fn jmap_tests() {
|
||||
mail::submission::test(&mut params).await;
|
||||
core::websocket::test(&mut params).await;
|
||||
auth::quota::test(&mut params).await;
|
||||
mail::crypto::test(&mut params).await;
|
||||
mail::crypto::test(&mut params).await;*/
|
||||
core::blob::test(&mut params).await;
|
||||
auth::permissions::test(¶ms).await;
|
||||
server::purge::test(&mut params).await;
|
||||
@@ -120,12 +127,63 @@ pub async fn jmap_metric_tests() {
|
||||
#[allow(dead_code)]
|
||||
pub struct JMAPTest {
|
||||
server: Server,
|
||||
client: Client,
|
||||
accounts: AHashMap<&'static str, Account>,
|
||||
temp_dir: TempDir,
|
||||
webhook: Arc<MockWebhookEndpoint>,
|
||||
shutdown_tx: watch::Sender<bool>,
|
||||
}
|
||||
|
||||
pub struct Account {
|
||||
name: &'static str,
|
||||
secret: &'static str,
|
||||
emails: &'static [&'static str],
|
||||
id: Id,
|
||||
id_string: String,
|
||||
client: Client,
|
||||
}
|
||||
|
||||
impl JMAPTest {
|
||||
pub fn account(&self, name: &str) -> &Account {
|
||||
self.accounts.get(name).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Account {
|
||||
pub fn id(&self) -> &Id {
|
||||
&self.id
|
||||
}
|
||||
|
||||
pub fn id_string(&self) -> &str {
|
||||
&self.id_string
|
||||
}
|
||||
|
||||
pub fn client(&self) -> &Client {
|
||||
&self.client
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
self.name
|
||||
}
|
||||
pub fn secret(&self) -> &str {
|
||||
self.secret
|
||||
}
|
||||
|
||||
pub fn emails(&self) -> &[&str] {
|
||||
self.emails
|
||||
}
|
||||
|
||||
pub async fn client_owned(&self) -> Client {
|
||||
Client::new()
|
||||
.credentials(Credentials::basic(self.name(), self.secret()))
|
||||
.timeout(Duration::from_secs(3600))
|
||||
.accept_invalid_certs(true)
|
||||
.follow_redirects(["127.0.0.1"])
|
||||
.connect("https://127.0.0.1:8899")
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn wait_for_index(server: &Server) {
|
||||
loop {
|
||||
let mut has_index_tasks = false;
|
||||
@@ -344,77 +402,177 @@ async fn init_jmap_tests(store_id: &str, delete_if_exists: bool) -> JMAPTest {
|
||||
}
|
||||
|
||||
// Create tables
|
||||
inner
|
||||
.shared_core
|
||||
.load()
|
||||
.storage
|
||||
.data
|
||||
.create_test_user("admin", "secret", "Superuser", &[])
|
||||
.await;
|
||||
let server = inner.build_server();
|
||||
let mut accounts = AHashMap::new();
|
||||
|
||||
// Create client
|
||||
let mut client = Client::new()
|
||||
.credentials(Credentials::basic("admin", "secret"))
|
||||
.timeout(Duration::from_secs(3600))
|
||||
.accept_invalid_certs(true)
|
||||
.follow_redirects(["127.0.0.1"])
|
||||
.connect("https://127.0.0.1:8899")
|
||||
.await
|
||||
.unwrap();
|
||||
client.set_default_account_id(Id::new(1));
|
||||
for (name, secret, description, emails) in [
|
||||
("admin", "secret", "Superuser", &[][..]),
|
||||
(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com", "john.doe@example.com"][..],
|
||||
),
|
||||
(
|
||||
"jane.smith@example.com",
|
||||
"abcde",
|
||||
"Jane Smith",
|
||||
&["jane.smith@example.com"],
|
||||
),
|
||||
(
|
||||
"bill@example.com",
|
||||
"098765",
|
||||
"Bill Foobar",
|
||||
&["bill@example.com"],
|
||||
),
|
||||
(
|
||||
"robert@example.com",
|
||||
"aabbcc",
|
||||
"Robert Foobar",
|
||||
&["robert@example.com"][..],
|
||||
),
|
||||
] {
|
||||
let id: Id = server
|
||||
.store()
|
||||
.create_test_user(name, secret, description, emails)
|
||||
.await
|
||||
.into();
|
||||
let id_string = id.to_string();
|
||||
|
||||
let mut client = Client::new()
|
||||
.credentials(Credentials::basic(name, secret))
|
||||
.timeout(Duration::from_secs(3600))
|
||||
.accept_invalid_certs(true)
|
||||
.follow_redirects(["127.0.0.1"])
|
||||
.connect("https://127.0.0.1:8899")
|
||||
.await
|
||||
.unwrap();
|
||||
client.set_default_account_id(id_string.clone());
|
||||
|
||||
accounts.insert(
|
||||
name,
|
||||
Account {
|
||||
name,
|
||||
secret,
|
||||
emails,
|
||||
id,
|
||||
id_string,
|
||||
client,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
for (name, description, emails) in
|
||||
[("sales@example.com", "Sales Group", &["sales@example.com"])]
|
||||
{
|
||||
let id: Id = server
|
||||
.store()
|
||||
.create_test_group(name, description, emails)
|
||||
.await
|
||||
.into();
|
||||
let id_string = id.to_string();
|
||||
|
||||
let mut client = Client::new()
|
||||
.credentials(Credentials::basic("admin", "secret"))
|
||||
.timeout(Duration::from_secs(3600))
|
||||
.accept_invalid_certs(true)
|
||||
.follow_redirects(["127.0.0.1"])
|
||||
.connect("https://127.0.0.1:8899")
|
||||
.await
|
||||
.unwrap();
|
||||
client.set_default_account_id(id_string.clone());
|
||||
|
||||
accounts.insert(
|
||||
name,
|
||||
Account {
|
||||
name,
|
||||
secret: "",
|
||||
emails,
|
||||
id,
|
||||
id_string,
|
||||
client,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
JMAPTest {
|
||||
server: inner.build_server(),
|
||||
server,
|
||||
temp_dir,
|
||||
client,
|
||||
accounts,
|
||||
shutdown_tx,
|
||||
webhook: spawn_mock_webhook_endpoint(),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn jmap_raw_request(body: impl AsRef<str>, username: &str, secret: &str) -> String {
|
||||
let mut headers = header::HeaderMap::new();
|
||||
pub struct JmapResponse(pub Value);
|
||||
|
||||
headers.insert(
|
||||
header::AUTHORIZATION,
|
||||
header::HeaderValue::from_str(&format!(
|
||||
"Basic {}",
|
||||
general_purpose::STANDARD.encode(format!("{}:{}", username, secret))
|
||||
))
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
const BODY_TEMPLATE: &str = r#"{
|
||||
"using": [ "urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail", "urn:ietf:params:jmap:quota" ],
|
||||
"methodCalls": $$
|
||||
}"#;
|
||||
|
||||
String::from_utf8(
|
||||
reqwest::Client::builder()
|
||||
.danger_accept_invalid_certs(true)
|
||||
.timeout(Duration::from_millis(1000))
|
||||
.default_headers(headers)
|
||||
.build()
|
||||
.unwrap()
|
||||
.post("https://127.0.0.1:8899/jmap")
|
||||
.body(BODY_TEMPLATE.replace("$$", body.as_ref()))
|
||||
.send()
|
||||
impl Account {
|
||||
pub async fn jmap_method_call(&self, method_name: &str, body: Value) -> JmapResponse {
|
||||
self.jmap_method_calls(json!([[method_name, body, "0"]]))
|
||||
.await
|
||||
.unwrap()
|
||||
.bytes()
|
||||
.await
|
||||
.unwrap()
|
||||
.to_vec(),
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub async fn jmap_method_calls(&self, calls: Value) -> JmapResponse {
|
||||
let mut headers = header::HeaderMap::new();
|
||||
|
||||
headers.insert(
|
||||
header::AUTHORIZATION,
|
||||
header::HeaderValue::from_str(&format!(
|
||||
"Basic {}",
|
||||
general_purpose::STANDARD.encode(format!("{}:{}", self.name(), self.secret()))
|
||||
))
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
let body = json!({
|
||||
"using": [ "urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail", "urn:ietf:params:jmap:quota" ],
|
||||
"methodCalls": calls
|
||||
});
|
||||
|
||||
JmapResponse(
|
||||
serde_json::from_slice(
|
||||
&reqwest::Client::builder()
|
||||
.danger_accept_invalid_certs(true)
|
||||
.timeout(Duration::from_millis(1000))
|
||||
.default_headers(headers)
|
||||
.build()
|
||||
.unwrap()
|
||||
.post("https://127.0.0.1:8899/jmap")
|
||||
.body(body.to_string())
|
||||
.send()
|
||||
.await
|
||||
.unwrap()
|
||||
.bytes()
|
||||
.await
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn jmap_json_request(
|
||||
body: impl AsRef<str>,
|
||||
username: &str,
|
||||
secret: &str,
|
||||
) -> serde_json::Value {
|
||||
serde_json::from_str(&jmap_raw_request(body, username, secret).await).unwrap()
|
||||
impl JmapResponse {
|
||||
pub fn pointer(&self, pointer: &str) -> Option<&Value> {
|
||||
self.0.pointer(pointer)
|
||||
}
|
||||
|
||||
pub fn into_inner(self) -> Value {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for JmapResponse {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for JmapResponse {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
serde_json::to_string_pretty(&self.0)
|
||||
.map_err(|_| std::fmt::Error)
|
||||
.and_then(|s| std::fmt::Display::fmt(&s, f))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn find_values(string: &str, name: &str) -> Vec<String> {
|
||||
@@ -473,17 +631,6 @@ pub fn replace_blob_ids(string: String) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn test_account_login(login: &str, secret: &str) -> Client {
|
||||
Client::new()
|
||||
.credentials(Credentials::basic(login, secret))
|
||||
.timeout(Duration::from_secs(5))
|
||||
.accept_invalid_certs(true)
|
||||
.follow_redirects(["127.0.0.1"])
|
||||
.connect("https://127.0.0.1:8899")
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum Response<T> {
|
||||
|
||||
@@ -127,22 +127,18 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
);
|
||||
|
||||
// Create test account
|
||||
params
|
||||
.server
|
||||
.inner
|
||||
.shared_core
|
||||
.load()
|
||||
.storage
|
||||
.data
|
||||
let server = params.server.inner.build_server();
|
||||
server
|
||||
.store()
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"secret",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com"],
|
||||
)
|
||||
.await;
|
||||
|
||||
alerts(¶ms.server.inner.build_server()).await;
|
||||
alerts(&server).await;
|
||||
undelete(params).await;
|
||||
tracing(params).await;
|
||||
metrics(params).await;
|
||||
@@ -351,9 +347,7 @@ async fn metrics(params: &mut JMAPTest) {
|
||||
async fn undelete(_params: &mut JMAPTest) {
|
||||
// Authenticate
|
||||
let mut imap = ImapConnection::connect(b"_x ").await;
|
||||
imap.send("AUTHENTICATE PLAIN {32+}\r\nAGpkb2VAZXhhbXBsZS5jb20Ac2VjcmV0")
|
||||
.await;
|
||||
imap.assert_read(Type::Tagged, ResponseType::Ok).await;
|
||||
imap.authenticate("jdoe@example.com", "12345").await;
|
||||
|
||||
// Insert test message
|
||||
imap.send("STATUS INBOX (MESSAGES)").await;
|
||||
@@ -390,9 +384,7 @@ async fn undelete(_params: &mut JMAPTest) {
|
||||
imap.send("LOGOUT").await;
|
||||
imap.assert_read(Type::Tagged, ResponseType::Ok).await;
|
||||
let mut imap = ImapConnection::connect(b"_x ").await;
|
||||
imap.send("AUTHENTICATE PLAIN {32+}\r\nAGpkb2VAZXhhbXBsZS5jb20Ac2VjcmV0")
|
||||
.await;
|
||||
imap.assert_read(Type::Tagged, ResponseType::Ok).await;
|
||||
imap.authenticate("jdoe@example.com", "12345").await;
|
||||
|
||||
// Make sure the message is gone
|
||||
imap.send("STATUS INBOX (MESSAGES)").await;
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
*/
|
||||
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
imap::{AssertResult, ImapConnection, Type},
|
||||
jmap::{JMAPTest, assert_is_empty},
|
||||
};
|
||||
@@ -24,23 +23,11 @@ use types::{collection::Collection, id::Id};
|
||||
pub async fn test(params: &mut JMAPTest) {
|
||||
println!("Running purge tests...");
|
||||
let server = params.server.clone();
|
||||
let client = &mut params.client;
|
||||
let inbox_id = Id::from(INBOX_ID).to_string();
|
||||
let trash_id = Id::from(TRASH_ID).to_string();
|
||||
let junk_id = Id::from(JUNK_ID).to_string();
|
||||
|
||||
// Connect to IMAP
|
||||
let account_id = server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com"],
|
||||
)
|
||||
.await;
|
||||
let account = params.account("jdoe@example.com");
|
||||
let client = account.client();
|
||||
|
||||
let mut imap = ImapConnection::connect(b"_x ").await;
|
||||
imap.assert_read(Type::Untagged, ResponseType::Ok).await;
|
||||
@@ -52,7 +39,6 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.assert_contains("MESSAGES 0");
|
||||
|
||||
// Create test messages
|
||||
client.set_default_account_id(Id::from(account_id));
|
||||
let mut message_ids = Vec::new();
|
||||
let mut pass = 0;
|
||||
let mut changes = AHashSet::new();
|
||||
@@ -107,7 +93,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
// Make sure both messages and changes are present
|
||||
assert_eq!(
|
||||
server
|
||||
.get_document_ids(account_id, Collection::Email)
|
||||
.get_document_ids(account.id().document_id(), Collection::Email)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
@@ -116,13 +102,16 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
);
|
||||
|
||||
// Purge junk/trash messages and old changes
|
||||
server.purge_account(account_id).await;
|
||||
let cache = server.get_cached_messages(account_id).await.unwrap();
|
||||
server.purge_account(account.id().document_id()).await;
|
||||
let cache = server
|
||||
.get_cached_messages(account.id().document_id())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Only 4 messages should remain
|
||||
assert_eq!(
|
||||
server
|
||||
.get_document_ids(account_id, Collection::Email)
|
||||
.get_document_ids(account.id().document_id(), Collection::Email)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
@@ -161,7 +150,7 @@ pub async fn test(params: &mut JMAPTest) {
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.delete_principal(QueryBy::Id(account_id))
|
||||
.delete_principal(QueryBy::Id(account.id().document_id()))
|
||||
.await
|
||||
.unwrap();
|
||||
assert_is_empty(server).await;
|
||||
|
||||
Reference in New Issue
Block a user