mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 21:46:35 +03:00
399 lines
14 KiB
Rust
399 lines
14 KiB
Rust
use num_traits::FromPrimitive;
|
|
|
|
use super::*;
|
|
use crate::test_utils::{TestContext, TestContextManager, sync};
|
|
|
|
#[test]
|
|
fn test_to_string() {
|
|
assert_eq!(Config::MailServer.to_string(), "mail_server");
|
|
assert_eq!(Config::from_str("mail_server"), Ok(Config::MailServer));
|
|
|
|
assert_eq!(Config::SysConfigKeys.to_string(), "sys.config_keys");
|
|
assert_eq!(
|
|
Config::from_str("sys.config_keys"),
|
|
Ok(Config::SysConfigKeys)
|
|
);
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn test_set_config_addr() {
|
|
let t = TestContext::new().await;
|
|
|
|
// Test that uppercase address get lowercased.
|
|
assert!(
|
|
t.set_config(Config::Addr, Some("Foobar@eXample.oRg"))
|
|
.await
|
|
.is_ok()
|
|
);
|
|
assert_eq!(
|
|
t.get_config(Config::Addr).await.unwrap().unwrap(),
|
|
"foobar@example.org"
|
|
);
|
|
}
|
|
|
|
/// Tests that "bot" config can only be set to "0" or "1".
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn test_set_config_bot() {
|
|
let t = TestContext::new().await;
|
|
|
|
assert!(t.set_config(Config::Bot, None).await.is_ok());
|
|
assert!(t.set_config(Config::Bot, Some("0")).await.is_ok());
|
|
assert!(t.set_config(Config::Bot, Some("1")).await.is_ok());
|
|
assert!(t.set_config(Config::Bot, Some("2")).await.is_err());
|
|
assert!(t.set_config(Config::Bot, Some("Foobar")).await.is_err());
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn test_media_quality_config_option() {
|
|
let t = TestContext::new().await;
|
|
let media_quality = t.get_config_int(Config::MediaQuality).await.unwrap();
|
|
assert_eq!(media_quality, 0);
|
|
let media_quality = constants::MediaQuality::from_i32(media_quality).unwrap_or_default();
|
|
assert_eq!(media_quality, constants::MediaQuality::Balanced);
|
|
|
|
t.set_config(Config::MediaQuality, Some("1")).await.unwrap();
|
|
|
|
let media_quality = t.get_config_int(Config::MediaQuality).await.unwrap();
|
|
assert_eq!(media_quality, 1);
|
|
assert_eq!(constants::MediaQuality::Worse as i32, 1);
|
|
let media_quality = constants::MediaQuality::from_i32(media_quality).unwrap_or_default();
|
|
assert_eq!(media_quality, constants::MediaQuality::Worse);
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn test_ui_config() -> Result<()> {
|
|
let t = TestContext::new().await;
|
|
|
|
assert_eq!(t.get_ui_config("ui.desktop.linux.systray").await?, None);
|
|
|
|
t.set_ui_config("ui.android.screen_security", Some("safe"))
|
|
.await?;
|
|
assert_eq!(
|
|
t.get_ui_config("ui.android.screen_security").await?,
|
|
Some("safe".to_string())
|
|
);
|
|
|
|
t.set_ui_config("ui.android.screen_security", None).await?;
|
|
assert_eq!(t.get_ui_config("ui.android.screen_security").await?, None);
|
|
|
|
assert!(t.set_ui_config("configured", Some("bar")).await.is_err());
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Regression test for https://github.com/deltachat/deltachat-core-rust/issues/3012
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn test_set_config_bool() -> Result<()> {
|
|
let t = TestContext::new().await;
|
|
|
|
// We need some config that defaults to true
|
|
let c = Config::MdnsEnabled;
|
|
assert_eq!(t.get_config_bool(c).await?, true);
|
|
t.set_config_bool(c, false).await?;
|
|
assert_eq!(t.get_config_bool(c).await?, false);
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn test_self_addrs() -> Result<()> {
|
|
let alice = TestContext::new_alice().await;
|
|
|
|
assert!(alice.is_self_addr("alice@example.org").await?);
|
|
assert_eq!(alice.get_all_self_addrs().await?, vec!["alice@example.org"]);
|
|
assert!(!alice.is_self_addr("alice@alice.com").await?);
|
|
|
|
// Test adding the same primary address
|
|
alice.set_primary_self_addr("alice@example.org").await?;
|
|
alice.set_primary_self_addr("Alice@Example.Org").await?;
|
|
assert_eq!(alice.get_all_self_addrs().await?, vec!["Alice@Example.Org"]);
|
|
|
|
// Test adding a new (primary) self address
|
|
// The address is trimmed during configure by `LoginParam::from_database()`,
|
|
// so `set_primary_self_addr()` doesn't have to trim it.
|
|
alice.set_primary_self_addr("Alice@alice.com").await?;
|
|
assert!(alice.is_self_addr("aliCe@example.org").await?);
|
|
assert!(alice.is_self_addr("alice@alice.com").await?);
|
|
assert_eq!(
|
|
alice.get_all_self_addrs().await?,
|
|
vec!["Alice@alice.com", "Alice@Example.Org"]
|
|
);
|
|
|
|
// Check that the entry is not duplicated
|
|
alice.set_primary_self_addr("alice@alice.com").await?;
|
|
alice.set_primary_self_addr("alice@alice.com").await?;
|
|
assert_eq!(
|
|
alice.get_all_self_addrs().await?,
|
|
vec!["alice@alice.com", "Alice@Example.Org"]
|
|
);
|
|
|
|
// Test switching back
|
|
alice.set_primary_self_addr("alice@example.org").await?;
|
|
assert_eq!(
|
|
alice.get_all_self_addrs().await?,
|
|
vec!["alice@example.org", "alice@alice.com"]
|
|
);
|
|
|
|
// Test setting a new primary self address, the previous self address
|
|
// should be kept as a secondary self address
|
|
alice.set_primary_self_addr("alice@alice.xyz").await?;
|
|
assert_eq!(
|
|
alice.get_all_self_addrs().await?,
|
|
vec!["alice@alice.xyz", "alice@example.org", "alice@alice.com"]
|
|
);
|
|
assert!(alice.is_self_addr("alice@example.org").await?);
|
|
assert!(alice.is_self_addr("alice@alice.com").await?);
|
|
assert!(alice.is_self_addr("Alice@alice.xyz").await?);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn test_mdns_default_behaviour() -> Result<()> {
|
|
let t = &TestContext::new_alice().await;
|
|
assert!(t.should_request_mdns().await?);
|
|
assert!(t.should_send_mdns().await?);
|
|
assert!(t.get_config_bool_opt(Config::MdnsEnabled).await?.is_none());
|
|
// The setting should be displayed correctly.
|
|
assert!(t.get_config_bool(Config::MdnsEnabled).await?);
|
|
|
|
t.set_config_bool(Config::Bot, true).await?;
|
|
assert!(!t.should_request_mdns().await?);
|
|
assert!(t.should_send_mdns().await?);
|
|
assert!(t.get_config_bool_opt(Config::MdnsEnabled).await?.is_none());
|
|
assert!(t.get_config_bool(Config::MdnsEnabled).await?);
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn test_delete_server_after_default() -> Result<()> {
|
|
let t = &TestContext::new_alice().await;
|
|
|
|
// Check that the settings are displayed correctly.
|
|
assert_eq!(t.get_config(Config::BccSelf).await?, Some("1".to_string()));
|
|
assert_eq!(
|
|
t.get_config(Config::DeleteServerAfter).await?,
|
|
Some("0".to_string())
|
|
);
|
|
|
|
// Leaving emails on the server even w/o `BccSelf` is a good default at least because other
|
|
// MUAs do so even if the server doesn't save sent messages to some sentbox (like Gmail
|
|
// does).
|
|
t.set_config_bool(Config::BccSelf, false).await?;
|
|
assert_eq!(
|
|
t.get_config(Config::DeleteServerAfter).await?,
|
|
Some("0".to_string())
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
const SAVED_MESSAGES_DEDUPLICATED_FILE: &str = "969142cb84015bc135767bc2370934a.png";
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn test_sync() -> Result<()> {
|
|
let alice0 = TestContext::new_alice().await;
|
|
let alice1 = TestContext::new_alice().await;
|
|
for a in [&alice0, &alice1] {
|
|
a.set_config_bool(Config::SyncMsgs, true).await?;
|
|
}
|
|
|
|
let mdns_enabled = alice0.get_config_bool(Config::MdnsEnabled).await?;
|
|
// Alice1 has a different config value.
|
|
alice1
|
|
.set_config_bool(Config::MdnsEnabled, !mdns_enabled)
|
|
.await?;
|
|
// This changes nothing, but still sends a sync message.
|
|
alice0
|
|
.set_config_bool(Config::MdnsEnabled, mdns_enabled)
|
|
.await?;
|
|
sync(&alice0, &alice1).await;
|
|
assert_eq!(
|
|
alice1.get_config_bool(Config::MdnsEnabled).await?,
|
|
mdns_enabled
|
|
);
|
|
|
|
// Reset to default. Test that it's not synced because defaults may differ across client
|
|
// versions.
|
|
alice0.set_config(Config::MdnsEnabled, None).await?;
|
|
alice0.set_config_bool(Config::MdnsEnabled, false).await?;
|
|
sync(&alice0, &alice1).await;
|
|
assert_eq!(alice1.get_config_bool(Config::MdnsEnabled).await?, false);
|
|
|
|
for key in [Config::ShowEmails, Config::MvboxMove] {
|
|
let val = alice0.get_config_bool(key).await?;
|
|
alice0.set_config_bool(key, !val).await?;
|
|
sync(&alice0, &alice1).await;
|
|
assert_eq!(alice1.get_config_bool(key).await?, !val);
|
|
}
|
|
|
|
// `Config::SyncMsgs` mustn't be synced.
|
|
alice0.set_config_bool(Config::SyncMsgs, false).await?;
|
|
alice0.set_config_bool(Config::SyncMsgs, true).await?;
|
|
alice0.set_config_bool(Config::MdnsEnabled, true).await?;
|
|
sync(&alice0, &alice1).await;
|
|
assert!(alice1.get_config_bool(Config::MdnsEnabled).await?);
|
|
|
|
// Usual sync scenario.
|
|
async fn test_config_str(
|
|
alice0: &TestContext,
|
|
alice1: &TestContext,
|
|
key: Config,
|
|
val: &str,
|
|
) -> Result<()> {
|
|
alice0.set_config(key, Some(val)).await?;
|
|
sync(alice0, alice1).await;
|
|
assert_eq!(alice1.get_config(key).await?, Some(val.to_string()));
|
|
Ok(())
|
|
}
|
|
test_config_str(&alice0, &alice1, Config::Displayname, "Alice Sync").await?;
|
|
test_config_str(&alice0, &alice1, Config::Selfstatus, "My status").await?;
|
|
|
|
assert!(alice0.get_config(Config::Selfavatar).await?.is_none());
|
|
let file = alice0.dir.path().join("avatar.png");
|
|
let bytes = include_bytes!("../../test-data/image/avatar64x64.png");
|
|
tokio::fs::write(&file, bytes).await?;
|
|
alice0
|
|
.set_config(Config::Selfavatar, Some(file.to_str().unwrap()))
|
|
.await?;
|
|
sync(&alice0, &alice1).await;
|
|
// There was a bug that a sync message creates the self-chat with the user avatar instead of
|
|
// the special icon and that remains so when the self-chat becomes user-visible. Let's check
|
|
// this.
|
|
let self_chat = alice0.get_self_chat().await;
|
|
let self_chat_avatar_path = self_chat.get_profile_image(&alice0).await?.unwrap();
|
|
assert_eq!(
|
|
self_chat_avatar_path,
|
|
alice0.get_blobdir().join(SAVED_MESSAGES_DEDUPLICATED_FILE)
|
|
);
|
|
assert!(
|
|
alice1
|
|
.get_config(Config::Selfavatar)
|
|
.await?
|
|
.filter(|path| path.ends_with(".png"))
|
|
.is_some()
|
|
);
|
|
alice0.set_config(Config::Selfavatar, None).await?;
|
|
sync(&alice0, &alice1).await;
|
|
assert!(alice1.get_config(Config::Selfavatar).await?.is_none());
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn test_no_sync_on_self_sent_msg() -> Result<()> {
|
|
let mut tcm = TestContextManager::new();
|
|
let alice0 = &tcm.alice().await;
|
|
let alice1 = &tcm.alice().await;
|
|
for a in [alice0, alice1] {
|
|
a.set_config_bool(Config::SyncMsgs, true).await?;
|
|
}
|
|
|
|
let status = "Sent via usual message";
|
|
alice0.set_config(Config::Selfstatus, Some(status)).await?;
|
|
alice0.send_sync_msg().await?;
|
|
alice0.pop_sent_sync_msg().await;
|
|
let status1 = "Synced via sync message";
|
|
alice1.set_config(Config::Selfstatus, Some(status1)).await?;
|
|
tcm.send_recv(alice0, alice1, "hi Alice!").await;
|
|
assert_eq!(
|
|
alice1.get_config(Config::Selfstatus).await?,
|
|
Some(status1.to_string())
|
|
);
|
|
sync(alice1, alice0).await;
|
|
assert_eq!(
|
|
alice0.get_config(Config::Selfstatus).await?,
|
|
Some(status1.to_string())
|
|
);
|
|
|
|
// Need a chat with another contact to send self-avatar.
|
|
let bob = &tcm.bob().await;
|
|
let a0b_chat_id = tcm.send_recv_accept(bob, alice0, "hi").await.chat_id;
|
|
let file = alice0.dir.path().join("avatar.png");
|
|
let bytes = include_bytes!("../../test-data/image/avatar64x64.png");
|
|
tokio::fs::write(&file, bytes).await?;
|
|
alice0
|
|
.set_config(Config::Selfavatar, Some(file.to_str().unwrap()))
|
|
.await?;
|
|
alice0.send_sync_msg().await?;
|
|
alice0.pop_sent_sync_msg().await;
|
|
let file = alice1.dir.path().join("avatar.jpg");
|
|
let bytes = include_bytes!("../../test-data/image/avatar1000x1000.jpg");
|
|
tokio::fs::write(&file, bytes).await?;
|
|
alice1
|
|
.set_config(Config::Selfavatar, Some(file.to_str().unwrap()))
|
|
.await?;
|
|
let sent_msg = alice0.send_text(a0b_chat_id, "hi").await;
|
|
alice1.recv_msg(&sent_msg).await;
|
|
assert!(
|
|
alice1
|
|
.get_config(Config::Selfavatar)
|
|
.await?
|
|
.filter(|path| path.ends_with(".jpg"))
|
|
.is_some()
|
|
);
|
|
sync(alice1, alice0).await;
|
|
assert!(
|
|
alice0
|
|
.get_config(Config::Selfavatar)
|
|
.await?
|
|
.filter(|path| path.ends_with(".jpg"))
|
|
.is_some()
|
|
);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn test_event_config_synced() -> Result<()> {
|
|
let alice0 = TestContext::new_alice().await;
|
|
let alice1 = TestContext::new_alice().await;
|
|
for a in [&alice0, &alice1] {
|
|
a.set_config_bool(Config::SyncMsgs, true).await?;
|
|
}
|
|
|
|
alice0
|
|
.set_config(Config::Displayname, Some("Alice Sync"))
|
|
.await?;
|
|
alice0
|
|
.evtracker
|
|
.get_matching(|e| {
|
|
matches!(
|
|
e,
|
|
EventType::ConfigSynced {
|
|
key: Config::Displayname
|
|
}
|
|
)
|
|
})
|
|
.await;
|
|
sync(&alice0, &alice1).await;
|
|
assert_eq!(
|
|
alice1.get_config(Config::Displayname).await?,
|
|
Some("Alice Sync".to_string())
|
|
);
|
|
alice1
|
|
.evtracker
|
|
.get_matching(|e| {
|
|
matches!(
|
|
e,
|
|
EventType::ConfigSynced {
|
|
key: Config::Displayname
|
|
}
|
|
)
|
|
})
|
|
.await;
|
|
|
|
alice0.set_config(Config::Displayname, None).await?;
|
|
alice0
|
|
.evtracker
|
|
.get_matching(|e| {
|
|
matches!(
|
|
e,
|
|
EventType::ConfigSynced {
|
|
key: Config::Displayname
|
|
}
|
|
)
|
|
})
|
|
.await;
|
|
|
|
Ok(())
|
|
}
|