Private
Public Access
1
0

Add 'core/' from commit 'b0dfc4146ca0da535a87f8509aec68817fb2ab14'

git-subtree-dir: core
git-subtree-mainline: a07f3dcd23
git-subtree-split: b0dfc4146c
This commit is contained in:
2025-09-06 19:33:33 -07:00
83 changed files with 12352 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
mod test_client;
use self::test_client::TestClient;
use crate::APIInterface;
pub mod api_interface {
use crate::model::Conversation;
use super::*;
#[tokio::test]
async fn test_version() {
let mut client = TestClient::new();
let version = client.get_version().await.unwrap();
assert_eq!(version, client.version);
}
#[tokio::test]
async fn test_conversations() {
let mut client = TestClient::new();
let test_convo = Conversation::builder()
.display_name("Test Conversation")
.build();
client.conversations.push(test_convo.clone());
let conversations = client.get_conversations().await.unwrap();
assert_eq!(conversations.len(), 1);
assert_eq!(conversations[0].display_name, test_convo.display_name);
}
}

View File

@@ -0,0 +1,158 @@
use async_trait::async_trait;
use std::collections::HashMap;
use time::OffsetDateTime;
use uuid::Uuid;
pub use crate::APIInterface;
use crate::{
api::event_socket::{EventSocket, SinkMessage, SocketEvent, SocketUpdate},
api::http_client::Credentials,
model::{
Conversation, ConversationID, Event, JwtToken, Message, MessageID, OutgoingMessage,
UpdateItem,
},
};
use bytes::Bytes;
use futures_util::stream::BoxStream;
use futures_util::Sink;
use futures_util::StreamExt;
pub struct TestClient {
pub version: &'static str,
pub conversations: Vec<Conversation>,
pub messages: HashMap<ConversationID, Vec<Message>>,
}
#[derive(Debug)]
pub enum TestError {
ConversationNotFound,
}
impl TestClient {
pub fn new() -> TestClient {
TestClient {
version: "KordophoneTest-1.0",
conversations: vec![],
messages: HashMap::<ConversationID, Vec<Message>>::new(),
}
}
}
pub struct TestEventSocket {
pub events: Vec<Event>,
}
impl TestEventSocket {
pub fn new() -> Self {
Self { events: vec![] }
}
}
#[async_trait]
impl EventSocket for TestEventSocket {
type Error = TestError;
type EventStream = BoxStream<'static, Result<SocketEvent, TestError>>;
type UpdateStream = BoxStream<'static, Result<SocketUpdate, TestError>>;
async fn events(
self,
) -> (
Self::EventStream,
impl Sink<SinkMessage, Error = Self::Error>,
) {
(
futures_util::stream::iter(self.events.into_iter().map(Ok)).boxed(),
futures_util::sink::sink(),
)
}
async fn raw_updates(self) -> Self::UpdateStream {
let results: Vec<Result<Vec<UpdateItem>, TestError>> = vec![];
futures_util::stream::iter(results.into_iter()).boxed()
}
}
#[async_trait]
impl APIInterface for TestClient {
type Error = TestError;
type ResponseStream = BoxStream<'static, Result<Bytes, TestError>>;
async fn authenticate(&mut self, _credentials: Credentials) -> Result<JwtToken, Self::Error> {
Ok(JwtToken::dummy())
}
async fn get_version(&mut self) -> Result<String, Self::Error> {
Ok(self.version.to_string())
}
async fn get_conversations(&mut self) -> Result<Vec<Conversation>, Self::Error> {
Ok(self.conversations.clone())
}
async fn get_messages(
&mut self,
conversation_id: &ConversationID,
limit: Option<u32>,
before: Option<MessageID>,
after: Option<MessageID>,
) -> Result<Vec<Message>, Self::Error> {
if let Some(messages) = self.messages.get(conversation_id) {
return Ok(messages.clone());
}
Err(TestError::ConversationNotFound)
}
async fn send_message(
&mut self,
outgoing_message: &OutgoingMessage,
) -> Result<Message, Self::Error> {
let message = Message::builder()
.guid(Uuid::new_v4().to_string())
.text(outgoing_message.text.clone())
.date(OffsetDateTime::now_utc())
.build();
self.messages
.entry(outgoing_message.conversation_id.clone())
.or_insert(vec![])
.push(message.clone());
Ok(message)
}
async fn open_event_socket(
&mut self,
_update_seq: Option<u64>,
) -> Result<impl EventSocket, Self::Error> {
Ok(TestEventSocket::new())
}
async fn fetch_attachment_data(
&mut self,
guid: &str,
preview: bool,
) -> Result<Self::ResponseStream, Self::Error> {
Ok(futures_util::stream::iter(vec![Ok(Bytes::from_static(b"test"))]).boxed())
}
async fn upload_attachment<R>(
&mut self,
data: tokio::io::BufReader<R>,
filename: &str,
size: u64,
) -> Result<String, Self::Error>
where
R: tokio::io::AsyncRead + Unpin + Send + Sync + 'static,
{
Ok(String::from("test"))
}
async fn mark_conversation_as_read(
&mut self,
conversation_id: &ConversationID,
) -> Result<(), Self::Error> {
Ok(())
}
}