use axum::extract::{Json, State}; use futures::{future, stream::StreamExt as _}; use crate::{ channel::{app, routes}, events::types, test::fixtures::{self, future::Immediately as _}, }; #[tokio::test] async fn new_channel() { // Set up the environment let app = fixtures::scratch_app().await; let creator = fixtures::login::create(&app).await; // Call the endpoint let name = fixtures::channel::propose(); let request = routes::CreateRequest { name }; let Json(response_channel) = routes::on_create( State(app.clone()), creator, fixtures::now(), Json(request.clone()), ) .await .expect("new channel in an empty app"); // Verify the structure of the response assert_eq!(request.name, response_channel.name); // Verify the semantics let channels = app.channels().all().await.expect("always succeeds"); assert!(channels.contains(&response_channel)); let mut events = app .events() .subscribe(&fixtures::now(), types::ResumePoint::default()) .await .expect("subscribing never fails") .filter(|types::ResumableEvent(_, event)| future::ready(event.channel == response_channel)); let types::ResumableEvent(_, event) = events .next() .immediately() .await .expect("creation event published"); assert_eq!(types::Sequence::default(), event.sequence); assert_eq!(types::ChannelEventData::Created, event.data); } #[tokio::test] async fn duplicate_name() { // Set up the environment let app = fixtures::scratch_app().await; let creator = fixtures::login::create(&app).await; let channel = fixtures::channel::create(&app, &fixtures::now()).await; // Call the endpoint let request = routes::CreateRequest { name: channel.name }; let routes::CreateError(error) = routes::on_create( State(app.clone()), creator, fixtures::now(), Json(request.clone()), ) .await .expect_err("duplicate channel name"); // Verify the structure of the response assert!(matches!( error, app::CreateError::DuplicateName(name) if request.name == name )); }