Compare commits

...

3 Commits

Author SHA1 Message Date
B. Petersen
3b1e11a28b feat: only convert Viewtype::Image to Audio/Video/Gif, Viewtype::File to Webxdc 2026-04-27 22:54:38 +02:00
link2xt
f239f8d2e4 test: test that File viewtype is not converted to Image 2026-04-27 22:54:13 +02:00
B. Petersen
00f911e030 feat: do not convert Viewtype::File to image 2026-04-27 22:50:01 +02:00
3 changed files with 56 additions and 26 deletions

View File

@@ -11,7 +11,7 @@ from unittest.mock import MagicMock
import pytest
from deltachat_rpc_client import EventType, events
from deltachat_rpc_client.const import DownloadState, MessageState
from deltachat_rpc_client.const import DownloadState, MessageState, ViewType
from deltachat_rpc_client.pytestplugin import E2EE_INFO_MSGS
from deltachat_rpc_client.rpc import JsonRpcError, Rpc
@@ -550,7 +550,7 @@ def test_import_export_online_all(acfactory, tmp_path, data, log) -> None:
assert len(ac1.get_contacts()) == 1
original_image_path = data.get_path("image/avatar64x64.png")
chat1.send_file(str(original_image_path))
chat1.send_message(file=str(original_image_path), viewtype=ViewType.IMAGE)
# Add another 100KB file that ensures that the progress is smooth enough
path = tmp_path / "attachment.txt"

View File

@@ -421,6 +421,7 @@ async fn test_recode_image_balanced_png() {
extension: "png",
original_width: 1920,
original_height: 1080,
res_viewtype: Some(Viewtype::File),
compressed_width: 1920,
compressed_height: 1080,
..Default::default()
@@ -436,6 +437,7 @@ async fn test_recode_image_balanced_png() {
extension: "png",
original_width: 1920,
original_height: 1080,
res_viewtype: Some(Viewtype::File),
compressed_width: 1920,
compressed_height: 1080,
set_draft: true,
@@ -605,8 +607,10 @@ impl SendImageCheckMediaquality<'_> {
}
let sent = alice.send_msg(chat.id, &mut msg).await;
let alice_msg = alice.get_last_msg().await;
assert_eq!(alice_msg.get_width() as u32, compressed_width);
assert_eq!(alice_msg.get_height() as u32, compressed_height);
if viewtype != Viewtype::File {
assert_eq!(alice_msg.get_width() as u32, compressed_width);
assert_eq!(alice_msg.get_height() as u32, compressed_height);
}
let file_saved = alice
.get_blobdir()
.join("saved-".to_string() + &alice_msg.get_filename().unwrap());
@@ -621,8 +625,10 @@ impl SendImageCheckMediaquality<'_> {
let bob_msg = bob.recv_msg(&sent).await;
assert_eq!(bob_msg.get_viewtype(), res_viewtype);
assert_eq!(bob_msg.get_width() as u32, compressed_width);
assert_eq!(bob_msg.get_height() as u32, compressed_height);
if viewtype != Viewtype::File {
assert_eq!(bob_msg.get_width() as u32, compressed_width);
assert_eq!(bob_msg.get_height() as u32, compressed_height);
}
let file_saved = bob
.get_blobdir()
.join("saved-".to_string() + &bob_msg.get_filename().unwrap());
@@ -738,6 +744,31 @@ async fn test_send_gif_as_sticker() -> Result<()> {
Ok(())
}
/// Tests that image sent with "File" viewtype keeps the viewtype
/// and is not converted into Image viewtype because of .png extension.
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_send_image_as_file() -> Result<()> {
let alice = &TestContext::new_alice().await;
let bytes = include_bytes!("../../test-data/image/logo.png");
let path = alice.get_blobdir().join("logo").with_extension("png");
fs::write(&path, bytes)
.await
.context("Failed to write file")?;
// Set image as file.
let mut msg = Message::new(Viewtype::File);
msg.set_file_and_deduplicate(alice, &path, None, None)?;
let chat = alice.get_self_chat().await;
let sent = alice.send_msg(chat.id, &mut msg).await;
let msg = Message::load_from_db(alice, sent.sender_msg_id).await?;
// Viewtype is still File, not converted to Image.
assert_eq!(msg.get_viewtype(), Viewtype::File);
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_create_and_deduplicate() -> Result<()> {
let t = TestContext::new().await;

View File

@@ -2465,26 +2465,25 @@ async fn prepare_msg_blob(context: &Context, msg: &mut Message) -> Result<()> {
.param
.get_file_blob(context)?
.with_context(|| format!("attachment missing for message of type #{}", msg.viewtype))?;
let mut maybe_image = false;
if msg.viewtype == Viewtype::File || msg.viewtype == Viewtype::Image {
// Correct the type, take care not to correct already very special
// formats as GIF or VOICE.
//
// Typical conversions:
// - from FILE to AUDIO/VIDEO/IMAGE
// - from FILE/IMAGE to GIF */
if let Some((better_type, _)) = message::guess_msgtype_from_suffix(msg) {
if better_type == Viewtype::Image {
maybe_image = true;
} else if better_type != Viewtype::Webxdc
|| context
.ensure_sendable_webxdc_file(&blob.to_abs_path())
.await
.is_ok()
{
msg.viewtype = better_type;
}
if msg.viewtype == Viewtype::Image {
if let Some((better_type, _)) = message::guess_msgtype_from_suffix(msg)
&& (better_type == Viewtype::Video
|| better_type == Viewtype::Audio
|| better_type == Viewtype::Gif)
{
msg.viewtype = better_type;
}
} else if msg.viewtype == Viewtype::File {
if let Some((better_type, _)) = message::guess_msgtype_from_suffix(msg)
&& (better_type == Viewtype::Vcard
|| better_type == Viewtype::Webxdc
&& context
.ensure_sendable_webxdc_file(&blob.to_abs_path())
.await
.is_ok())
{
msg.viewtype = better_type;
}
} else if msg.viewtype == Viewtype::Webxdc {
context
@@ -2495,7 +2494,7 @@ async fn prepare_msg_blob(context: &Context, msg: &mut Message) -> Result<()> {
if msg.viewtype == Viewtype::Vcard {
msg.try_set_vcard(context, &blob.to_abs_path()).await?;
}
if msg.viewtype == Viewtype::File && maybe_image || msg.viewtype == Viewtype::Image {
if msg.viewtype == Viewtype::Image {
let new_name = blob
.check_or_recode_image(context, msg.get_filename(), &mut msg.viewtype)
.await?;