feat(chat): colle les fichiers du presse-papiers via Ctrl+V dans le composer (#181)
This commit is contained in:
@ -12,7 +12,7 @@ use uuid::Uuid;
|
||||
|
||||
use application::{
|
||||
ImportChatAttachmentItem, ImportChatAttachmentSource, ImportChatAttachments,
|
||||
ImportChatAttachmentsInput,
|
||||
ImportChatAttachmentsInput, CHAT_ATTACHMENT_MAX_BYTES,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
@ -220,6 +220,109 @@ async fn import_chat_attachments_routes_clipboard_bytes_to_store_port() {
|
||||
assert_eq!(calls[0].1.filename, "clipboard.png");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn import_chat_attachments_accepts_generic_clipboard_file_bytes() {
|
||||
let store = Arc::new(FakeChatAttachments::default());
|
||||
let usecase = ImportChatAttachments::new(
|
||||
Arc::clone(&store) as Arc<dyn ChatAttachmentStore>,
|
||||
Arc::new(FixedIds),
|
||||
Arc::new(FixedClock),
|
||||
);
|
||||
|
||||
let output = usecase
|
||||
.execute(ImportChatAttachmentsInput {
|
||||
project: project(),
|
||||
agent_id: AgentId::new_random(),
|
||||
session_id: SessionId::new_random(),
|
||||
attachments: vec![ImportChatAttachmentItem {
|
||||
source: ImportChatAttachmentSource::Bytes {
|
||||
filename: "clipboard.pdf".to_owned(),
|
||||
bytes: b"%PDF-1.7".to_vec(),
|
||||
},
|
||||
mime: Some("application/pdf".to_owned()),
|
||||
source_kind: ChatAttachmentSourceKind::Clipboard,
|
||||
}],
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(output.attachments[0].filename, "clipboard.pdf");
|
||||
assert_eq!(output.attachments[0].mime, "application/pdf");
|
||||
assert_eq!(
|
||||
output.attachments[0].source_kind,
|
||||
ChatAttachmentSourceKind::Clipboard
|
||||
);
|
||||
let calls = store.bytes_calls.lock().unwrap();
|
||||
assert_eq!(calls.len(), 1);
|
||||
assert_eq!(calls[0].0, b"%PDF-1.7");
|
||||
assert_eq!(calls[0].1.filename, "clipboard.pdf");
|
||||
assert_eq!(calls[0].1.mime, "application/pdf");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn import_chat_attachments_rejects_oversized_clipboard_bytes_before_store_call() {
|
||||
let store = Arc::new(FakeChatAttachments::default());
|
||||
let usecase = ImportChatAttachments::new(
|
||||
Arc::clone(&store) as Arc<dyn ChatAttachmentStore>,
|
||||
Arc::new(FixedIds),
|
||||
Arc::new(FixedClock),
|
||||
);
|
||||
|
||||
let err = usecase
|
||||
.execute(ImportChatAttachmentsInput {
|
||||
project: project(),
|
||||
agent_id: AgentId::new_random(),
|
||||
session_id: SessionId::new_random(),
|
||||
attachments: vec![ImportChatAttachmentItem {
|
||||
source: ImportChatAttachmentSource::Bytes {
|
||||
filename: "too-big.pdf".to_owned(),
|
||||
bytes: vec![0; (CHAT_ATTACHMENT_MAX_BYTES + 1) as usize],
|
||||
},
|
||||
mime: Some("application/pdf".to_owned()),
|
||||
source_kind: ChatAttachmentSourceKind::Clipboard,
|
||||
}],
|
||||
})
|
||||
.await
|
||||
.unwrap_err();
|
||||
|
||||
assert_eq!(err.code(), "INVALID");
|
||||
assert!(err.to_string().contains("chat attachment exceeds"));
|
||||
assert!(store.path_calls.lock().unwrap().is_empty());
|
||||
assert!(store.bytes_calls.lock().unwrap().is_empty());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn import_chat_attachments_rejects_empty_clipboard_bytes_before_store_call() {
|
||||
let store = Arc::new(FakeChatAttachments::default());
|
||||
let usecase = ImportChatAttachments::new(
|
||||
Arc::clone(&store) as Arc<dyn ChatAttachmentStore>,
|
||||
Arc::new(FixedIds),
|
||||
Arc::new(FixedClock),
|
||||
);
|
||||
|
||||
let err = usecase
|
||||
.execute(ImportChatAttachmentsInput {
|
||||
project: project(),
|
||||
agent_id: AgentId::new_random(),
|
||||
session_id: SessionId::new_random(),
|
||||
attachments: vec![ImportChatAttachmentItem {
|
||||
source: ImportChatAttachmentSource::Bytes {
|
||||
filename: "empty.txt".to_owned(),
|
||||
bytes: Vec::new(),
|
||||
},
|
||||
mime: Some("text/plain".to_owned()),
|
||||
source_kind: ChatAttachmentSourceKind::Clipboard,
|
||||
}],
|
||||
})
|
||||
.await
|
||||
.unwrap_err();
|
||||
|
||||
assert_eq!(err.code(), "INVALID");
|
||||
assert!(err.to_string().contains("chat attachment must not be empty"));
|
||||
assert!(store.path_calls.lock().unwrap().is_empty());
|
||||
assert!(store.bytes_calls.lock().unwrap().is_empty());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn import_chat_attachments_rejects_executable_sources_before_store_call() {
|
||||
let store = Arc::new(FakeChatAttachments::default());
|
||||
|
||||
Reference in New Issue
Block a user