summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app.rs10
-rw-r--r--src/conversation/app.rs10
-rw-r--r--src/conversation/handlers/create/mod.rs8
-rw-r--r--src/conversation/handlers/create/test.rs66
-rw-r--r--src/conversation/handlers/delete/mod.rs9
-rw-r--r--src/conversation/handlers/delete/test.rs12
-rw-r--r--src/test/fixtures/conversation.rs11
-rw-r--r--src/ui/handlers/conversation.rs7
8 files changed, 78 insertions, 55 deletions
diff --git a/src/app.rs b/src/app.rs
index e33ee39..3f3885a 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -38,8 +38,8 @@ impl App {
Boot::new(self.db.clone())
}
- pub const fn conversations(&self) -> Conversations<'_> {
- Conversations::new(&self.db, &self.events)
+ pub fn conversations(&self) -> Conversations {
+ Conversations::new(self.db.clone(), self.events.clone())
}
pub const fn events(&self) -> Events<'_> {
@@ -77,3 +77,9 @@ impl FromRef<App> for Boot {
app.boot()
}
}
+
+impl FromRef<App> for Conversations {
+ fn from_ref(app: &App) -> Self {
+ app.conversations()
+ }
+}
diff --git a/src/conversation/app.rs b/src/conversation/app.rs
index 26886af..2b62e77 100644
--- a/src/conversation/app.rs
+++ b/src/conversation/app.rs
@@ -15,13 +15,13 @@ use crate::{
name::{self, Name},
};
-pub struct Conversations<'a> {
- db: &'a SqlitePool,
- events: &'a Broadcaster,
+pub struct Conversations {
+ db: SqlitePool,
+ events: Broadcaster,
}
-impl<'a> Conversations<'a> {
- pub const fn new(db: &'a SqlitePool, events: &'a Broadcaster) -> Self {
+impl Conversations {
+ pub const fn new(db: SqlitePool, events: Broadcaster) -> Self {
Self { db, events }
}
diff --git a/src/conversation/handlers/create/mod.rs b/src/conversation/handlers/create/mod.rs
index 18eca1f..2b7fa39 100644
--- a/src/conversation/handlers/create/mod.rs
+++ b/src/conversation/handlers/create/mod.rs
@@ -5,9 +5,8 @@ use axum::{
};
use crate::{
- app::App,
clock::RequestedAt,
- conversation::{Conversation, app},
+ conversation::{Conversation, app, app::Conversations},
error::Internal,
name::Name,
token::extract::Identity,
@@ -17,13 +16,12 @@ use crate::{
mod test;
pub async fn handler(
- State(app): State<App>,
+ State(conversations): State<Conversations>,
_: Identity, // requires auth, but doesn't actually care who you are
RequestedAt(created_at): RequestedAt,
Json(request): Json<Request>,
) -> Result<Response, Error> {
- let conversation = app
- .conversations()
+ let conversation = conversations
.create(&request.name, &created_at)
.await
.map_err(Error)?;
diff --git a/src/conversation/handlers/create/test.rs b/src/conversation/handlers/create/test.rs
index bc05b00..380bb13 100644
--- a/src/conversation/handlers/create/test.rs
+++ b/src/conversation/handlers/create/test.rs
@@ -22,10 +22,14 @@ async fn new_conversation() {
let name = fixtures::conversation::propose();
let request = super::Request { name: name.clone() };
- let super::Response(response) =
- super::handler(State(app.clone()), creator, fixtures::now(), Json(request))
- .await
- .expect("creating a conversation in an empty app succeeds");
+ let super::Response(response) = super::handler(
+ State(app.conversations()),
+ creator,
+ fixtures::now(),
+ Json(request),
+ )
+ .await
+ .expect("creating a conversation in an empty app succeeds");
// Verify the structure of the response
@@ -77,10 +81,14 @@ async fn duplicate_name() {
let request = super::Request {
name: conversation.name.clone(),
};
- let super::Error(error) =
- super::handler(State(app.clone()), creator, fixtures::now(), Json(request))
- .await
- .expect_err("duplicate conversation name should fail the request");
+ let super::Error(error) = super::handler(
+ State(app.conversations()),
+ creator,
+ fixtures::now(),
+ Json(request),
+ )
+ .await
+ .expect_err("duplicate conversation name should fail the request");
// Verify the structure of the response
@@ -110,10 +118,14 @@ async fn conflicting_canonical_name() {
let request = super::Request {
name: conflicting_name.clone(),
};
- let super::Error(error) =
- super::handler(State(app.clone()), creator, fixtures::now(), Json(request))
- .await
- .expect_err("duplicate conversation name should fail the request");
+ let super::Error(error) = super::handler(
+ State(app.conversations()),
+ creator,
+ fixtures::now(),
+ Json(request),
+ )
+ .await
+ .expect_err("duplicate conversation name should fail the request");
// Verify the structure of the response
@@ -135,7 +147,7 @@ async fn invalid_name() {
let name = fixtures::conversation::propose_invalid_name();
let request = super::Request { name: name.clone() };
let super::Error(error) = crate::conversation::handlers::create::handler(
- State(app.clone()),
+ State(app.conversations()),
creator,
fixtures::now(),
Json(request),
@@ -163,7 +175,7 @@ async fn name_reusable_after_delete() {
let request = super::Request { name: name.clone() };
let super::Response(response) = super::handler(
- State(app.clone()),
+ State(app.conversations()),
creator.clone(),
fixtures::now(),
Json(request),
@@ -181,10 +193,14 @@ async fn name_reusable_after_delete() {
// Call the endpoint (second time)
let request = super::Request { name: name.clone() };
- let super::Response(response) =
- super::handler(State(app.clone()), creator, fixtures::now(), Json(request))
- .await
- .expect("creation succeeds after original conversation deleted");
+ let super::Response(response) = super::handler(
+ State(app.conversations()),
+ creator,
+ fixtures::now(),
+ Json(request),
+ )
+ .await
+ .expect("creation succeeds after original conversation deleted");
// Verify the structure of the response
@@ -212,7 +228,7 @@ async fn name_reusable_after_expiry() {
let request = super::Request { name: name.clone() };
let super::Response(_) = super::handler(
- State(app.clone()),
+ State(app.conversations()),
creator.clone(),
fixtures::ancient(),
Json(request),
@@ -230,10 +246,14 @@ async fn name_reusable_after_expiry() {
// Call the endpoint (second time)
let request = super::Request { name: name.clone() };
- let super::Response(response) =
- super::handler(State(app.clone()), creator, fixtures::now(), Json(request))
- .await
- .expect("creation succeeds after original conversation expired");
+ let super::Response(response) = super::handler(
+ State(app.conversations()),
+ creator,
+ fixtures::now(),
+ Json(request),
+ )
+ .await
+ .expect("creation succeeds after original conversation expired");
// Verify the structure of the response
diff --git a/src/conversation/handlers/delete/mod.rs b/src/conversation/handlers/delete/mod.rs
index 272165a..231e433 100644
--- a/src/conversation/handlers/delete/mod.rs
+++ b/src/conversation/handlers/delete/mod.rs
@@ -5,9 +5,8 @@ use axum::{
};
use crate::{
- app::App,
clock::RequestedAt,
- conversation::{self, app, handlers::PathInfo},
+ conversation::{self, app, app::Conversations, handlers::PathInfo},
error::{Internal, NotFound},
token::extract::Identity,
};
@@ -16,14 +15,12 @@ use crate::{
mod test;
pub async fn handler(
- State(app): State<App>,
+ State(conversations): State<Conversations>,
Path(conversation): Path<PathInfo>,
RequestedAt(deleted_at): RequestedAt,
_: Identity,
) -> Result<Response, Error> {
- app.conversations()
- .delete(&conversation, &deleted_at)
- .await?;
+ conversations.delete(&conversation, &deleted_at).await?;
Ok(Response { id: conversation })
}
diff --git a/src/conversation/handlers/delete/test.rs b/src/conversation/handlers/delete/test.rs
index 2718d3b..e9e882a 100644
--- a/src/conversation/handlers/delete/test.rs
+++ b/src/conversation/handlers/delete/test.rs
@@ -14,7 +14,7 @@ pub async fn valid_conversation() {
let deleter = fixtures::identity::create(&app, &fixtures::now()).await;
let response = super::handler(
- State(app.clone()),
+ State(app.conversations()),
Path(conversation.id.clone()),
fixtures::now(),
deleter,
@@ -52,7 +52,7 @@ pub async fn invalid_conversation_id() {
let deleter = fixtures::identity::create(&app, &fixtures::now()).await;
let conversation = fixtures::conversation::fictitious();
let super::Error(error) = super::handler(
- State(app.clone()),
+ State(app.conversations()),
Path(conversation.clone()),
fixtures::now(),
deleter,
@@ -81,7 +81,7 @@ pub async fn conversation_deleted() {
let deleter = fixtures::identity::create(&app, &fixtures::now()).await;
let super::Error(error) = super::handler(
- State(app.clone()),
+ State(app.conversations()),
Path(conversation.id.clone()),
fixtures::now(),
deleter,
@@ -110,7 +110,7 @@ pub async fn conversation_expired() {
let deleter = fixtures::identity::create(&app, &fixtures::now()).await;
let super::Error(error) = super::handler(
- State(app.clone()),
+ State(app.conversations()),
Path(conversation.id.clone()),
fixtures::now(),
deleter,
@@ -144,7 +144,7 @@ pub async fn conversation_purged() {
let deleter = fixtures::identity::create(&app, &fixtures::now()).await;
let super::Error(error) = super::handler(
- State(app.clone()),
+ State(app.conversations()),
Path(conversation.id.clone()),
fixtures::now(),
deleter,
@@ -170,7 +170,7 @@ pub async fn conversation_not_empty() {
let deleter = fixtures::identity::create(&app, &fixtures::now()).await;
let super::Error(error) = super::handler(
- State(app.clone()),
+ State(app.conversations()),
Path(conversation.id.clone()),
fixtures::now(),
deleter,
diff --git a/src/test/fixtures/conversation.rs b/src/test/fixtures/conversation.rs
index fb2f58d..f0d8c8c 100644
--- a/src/test/fixtures/conversation.rs
+++ b/src/test/fixtures/conversation.rs
@@ -1,3 +1,4 @@
+use axum::extract::FromRef;
use faker_rand::{
en_us::{addresses::CityName, names::FullName},
faker_impl_from_templates,
@@ -6,15 +7,17 @@ use faker_rand::{
use rand;
use crate::{
- app::App,
clock::RequestedAt,
- conversation::{self, Conversation},
+ conversation::{self, Conversation, app::Conversations},
name::Name,
};
-pub async fn create(app: &App, created_at: &RequestedAt) -> Conversation {
+pub async fn create<App>(app: &App, created_at: &RequestedAt) -> Conversation
+where
+ Conversations: FromRef<App>,
+{
let name = propose();
- app.conversations()
+ Conversations::from_ref(app)
.create(&name, created_at)
.await
.expect("should always succeed if the conversation is actually new")
diff --git a/src/ui/handlers/conversation.rs b/src/ui/handlers/conversation.rs
index f1bb319..2ff090c 100644
--- a/src/ui/handlers/conversation.rs
+++ b/src/ui/handlers/conversation.rs
@@ -4,8 +4,7 @@ use axum::{
};
use crate::{
- app::App,
- conversation::{self, app},
+ conversation::{self, app, app::Conversations},
error::Internal,
token::extract::Identity,
ui::{
@@ -15,12 +14,12 @@ use crate::{
};
pub async fn handler(
- State(app): State<App>,
+ State(conversations): State<Conversations>,
identity: Option<Identity>,
Path(conversation): Path<conversation::Id>,
) -> Result<Asset, Error> {
let _ = identity.ok_or(Error::NotLoggedIn)?;
- app.conversations()
+ conversations
.get(&conversation)
.await
.map_err(Error::from)?;