summaryrefslogtreecommitdiff
path: root/src/channel/handlers/send/test.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/channel/handlers/send/test.rs')
-rw-r--r--src/channel/handlers/send/test.rs131
1 files changed, 131 insertions, 0 deletions
diff --git a/src/channel/handlers/send/test.rs b/src/channel/handlers/send/test.rs
new file mode 100644
index 0000000..f43f901
--- /dev/null
+++ b/src/channel/handlers/send/test.rs
@@ -0,0 +1,131 @@
+use axum::extract::{Json, Path, State};
+use futures::stream::{self, StreamExt as _};
+
+use crate::{
+ channel,
+ event::Sequenced,
+ message::app::SendError,
+ test::fixtures::{self, future::Expect as _},
+};
+
+#[tokio::test]
+async fn messages_in_order() {
+ // Set up the environment
+
+ let app = fixtures::scratch_app().await;
+ let sender = fixtures::identity::create(&app, &fixtures::now()).await;
+ let channel = fixtures::channel::create(&app, &fixtures::now()).await;
+ let resume_point = fixtures::boot::resume_point(&app).await;
+
+ // Call the endpoint (twice)
+
+ let requests = vec![
+ (fixtures::now(), fixtures::message::propose()),
+ (fixtures::now(), fixtures::message::propose()),
+ ];
+
+ for (sent_at, body) in &requests {
+ let request = super::Request { body: body.clone() };
+
+ let _ = super::handler(
+ State(app.clone()),
+ Path(channel.id.clone()),
+ sent_at.clone(),
+ sender.clone(),
+ Json(request),
+ )
+ .await
+ .expect("sending to a valid channel succeeds");
+ }
+
+ // Verify the semantics
+
+ let mut events = app
+ .events()
+ .subscribe(resume_point)
+ .await
+ .expect("subscribing to a valid channel succeeds")
+ .filter_map(fixtures::event::message)
+ .filter_map(fixtures::event::message::sent)
+ .zip(stream::iter(requests));
+
+ while let Some((event, (sent_at, body))) = events
+ .next()
+ .expect_ready("an event should be ready for each message")
+ .await
+ {
+ assert_eq!(*sent_at, event.at());
+ assert_eq!(sender.user.id, event.message.sender);
+ assert_eq!(body, event.message.body);
+ }
+}
+
+#[tokio::test]
+async fn nonexistent_channel() {
+ // Set up the environment
+
+ let app = fixtures::scratch_app().await;
+ let sender = fixtures::identity::create(&app, &fixtures::now()).await;
+
+ // Call the endpoint
+
+ let sent_at = fixtures::now();
+ let channel = channel::Id::generate();
+ let request = super::Request {
+ body: fixtures::message::propose(),
+ };
+ let super::Error(error) = super::handler(
+ State(app),
+ Path(channel.clone()),
+ sent_at,
+ sender,
+ Json(request),
+ )
+ .await
+ .expect_err("sending to a nonexistent channel fails");
+
+ // Verify the structure of the response
+
+ assert!(matches!(
+ error,
+ SendError::ChannelNotFound(error_channel) if channel == error_channel
+ ));
+}
+
+#[tokio::test]
+async fn deleted_channel() {
+ // Set up the environment
+
+ let app = fixtures::scratch_app().await;
+ let sender = fixtures::identity::create(&app, &fixtures::now()).await;
+ let channel = fixtures::channel::create(&app, &fixtures::now()).await;
+
+ app.channels()
+ .delete(&channel.id, &fixtures::now())
+ .await
+ .expect("deleting a new channel succeeds");
+
+ // Call the endpoint
+
+ let sent_at = fixtures::now();
+ let channel = channel::Id::generate();
+ let request = super::Request {
+ body: fixtures::message::propose(),
+ };
+ let super::Error(error) = super::handler(
+ State(app),
+ Path(channel.clone()),
+ sent_at,
+ sender,
+ Json(request),
+ )
+ .await
+ .expect_err("sending to a deleted channel fails");
+
+ // Verify the structure of the response
+
+ assert!(matches!(
+ error,
+ SendError::ChannelNotFound(error_channel) if channel == error_channel
+ ));
+}