summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorOwen Jacobson <owen@grimoire.ca>2024-10-24 19:49:54 -0400
committerOwen Jacobson <owen@grimoire.ca>2024-10-24 19:49:54 -0400
commitf9cbf95e5b850a7407c34f936c0f858520682a5d (patch)
tree31c67535f6e598b83dc3e752ce0a0727fc817fcd /src
parent461814e5174cef1be3e07b4e4069314e9bcbedd6 (diff)
Tests for retrieving invites
Diffstat (limited to 'src')
-rw-r--r--src/channel/routes/channel/test/delete.rs10
-rw-r--r--src/clock.rs2
-rw-r--r--src/invite/app.rs6
-rw-r--r--src/invite/mod.rs2
-rw-r--r--src/invite/routes/invite/mod.rs2
-rw-r--r--src/invite/routes/invite/test/get.rs65
-rw-r--r--src/invite/routes/invite/test/mod.rs1
-rw-r--r--src/invite/routes/mod.rs2
-rw-r--r--src/invite/routes/post.rs2
-rw-r--r--src/invite/routes/test.rs28
-rw-r--r--src/test/fixtures/invite.rs17
-rw-r--r--src/test/fixtures/mod.rs1
12 files changed, 125 insertions, 13 deletions
diff --git a/src/channel/routes/channel/test/delete.rs b/src/channel/routes/channel/test/delete.rs
index e9af12f..e1210fd 100644
--- a/src/channel/routes/channel/test/delete.rs
+++ b/src/channel/routes/channel/test/delete.rs
@@ -9,7 +9,7 @@ use crate::{
};
#[tokio::test]
-pub async fn delete_channel() {
+pub async fn valid_channel() {
// Set up the environment
let app = fixtures::scratch_app().await;
@@ -38,7 +38,7 @@ pub async fn delete_channel() {
}
#[tokio::test]
-pub async fn delete_invalid_channel_id() {
+pub async fn invalid_channel_id() {
// Set up the environment
let app = fixtures::scratch_app().await;
@@ -62,7 +62,7 @@ pub async fn delete_invalid_channel_id() {
}
#[tokio::test]
-pub async fn delete_deleted() {
+pub async fn channel_deleted() {
// Set up the environment
let app = fixtures::scratch_app().await;
@@ -91,7 +91,7 @@ pub async fn delete_deleted() {
}
#[tokio::test]
-pub async fn delete_expired() {
+pub async fn channel_expired() {
// Set up the environment
let app = fixtures::scratch_app().await;
@@ -120,7 +120,7 @@ pub async fn delete_expired() {
}
#[tokio::test]
-pub async fn delete_purged() {
+pub async fn channel_purged() {
// Set up the environment
let app = fixtures::scratch_app().await;
diff --git a/src/clock.rs b/src/clock.rs
index 9ffef82..242bcdf 100644
--- a/src/clock.rs
+++ b/src/clock.rs
@@ -12,7 +12,7 @@ pub type DateTime = chrono::DateTime<chrono::Utc>;
// calculated once per request, even if the extractor is used in multiple
// places. This requires the [middleware] function to be installed with
// [axum::middleware::from_fn] around the current route.
-#[derive(Clone)]
+#[derive(Debug, Clone)]
pub struct RequestedAt(pub DateTime);
impl RequestedAt {
diff --git a/src/invite/app.rs b/src/invite/app.rs
index 64ba753..65e7721 100644
--- a/src/invite/app.rs
+++ b/src/invite/app.rs
@@ -20,11 +20,7 @@ impl<'a> Invites<'a> {
Self { db }
}
- pub async fn create(
- &self,
- issuer: &Login,
- issued_at: &DateTime,
- ) -> Result<Invite, sqlx::Error> {
+ pub async fn issue(&self, issuer: &Login, issued_at: &DateTime) -> Result<Invite, sqlx::Error> {
let mut tx = self.db.begin().await?;
let invite = tx.invites().create(issuer, issued_at).await?;
tx.commit().await?;
diff --git a/src/invite/mod.rs b/src/invite/mod.rs
index d59fb9c..53ca984 100644
--- a/src/invite/mod.rs
+++ b/src/invite/mod.rs
@@ -14,7 +14,7 @@ pub struct Invite {
pub issued_at: DateTime,
}
-#[derive(serde::Serialize)]
+#[derive(Debug, serde::Serialize)]
pub struct Summary {
pub id: Id,
pub issuer: nfc::String,
diff --git a/src/invite/routes/invite/mod.rs b/src/invite/routes/invite/mod.rs
index 04593fd..c22029a 100644
--- a/src/invite/routes/invite/mod.rs
+++ b/src/invite/routes/invite/mod.rs
@@ -1,4 +1,6 @@
pub mod get;
pub mod post;
+#[cfg(test)]
+pub mod test;
type PathInfo = crate::invite::Id;
diff --git a/src/invite/routes/invite/test/get.rs b/src/invite/routes/invite/test/get.rs
new file mode 100644
index 0000000..c6780ed
--- /dev/null
+++ b/src/invite/routes/invite/test/get.rs
@@ -0,0 +1,65 @@
+use axum::extract::{Json, Path, State};
+
+use crate::{invite::routes::invite::get, test::fixtures};
+
+#[tokio::test]
+async fn valid_invite() {
+ // Set up the environment
+
+ let app = fixtures::scratch_app().await;
+ let issuer = fixtures::login::create(&app, &fixtures::now()).await;
+ let invite = fixtures::invite::issue(&app, &issuer, &fixtures::now()).await;
+
+ // Call endpoint
+
+ let Json(response) = get::handler(State(app), Path(invite.id))
+ .await
+ .expect("get for an existing invite succeeds");
+
+ // Verify response
+
+ assert_eq!(issuer.name.display(), &response.issuer);
+ assert_eq!(invite.issued_at, response.issued_at);
+}
+
+#[tokio::test]
+async fn nonexistent_invite() {
+ // Set up the environment
+
+ let app = fixtures::scratch_app().await;
+
+ // Call endpoint
+
+ let invite = fixtures::invite::fictitious();
+ let error = get::handler(State(app), Path(invite.clone()))
+ .await
+ .expect_err("get for a nonexistent invite fails");
+
+ // Verify response
+
+ assert!(matches!(error, get::Error::NotFound(error_id) if invite == error_id));
+}
+
+#[tokio::test]
+async fn expired_invite() {
+ // Set up the environment
+
+ let app = fixtures::scratch_app().await;
+ let issuer = fixtures::login::create(&app, &fixtures::ancient()).await;
+ let invite = fixtures::invite::issue(&app, &issuer, &fixtures::ancient()).await;
+
+ app.invites()
+ .expire(&fixtures::now())
+ .await
+ .expect("expiring invites never fails");
+
+ // Call endpoint
+
+ let error = get::handler(State(app), Path(invite.id.clone()))
+ .await
+ .expect_err("get for an expired invite fails");
+
+ // Verify response
+
+ assert!(matches!(error, get::Error::NotFound(error_id) if invite.id == error_id));
+}
diff --git a/src/invite/routes/invite/test/mod.rs b/src/invite/routes/invite/test/mod.rs
new file mode 100644
index 0000000..a608fbb
--- /dev/null
+++ b/src/invite/routes/invite/test/mod.rs
@@ -0,0 +1 @@
+mod get;
diff --git a/src/invite/routes/mod.rs b/src/invite/routes/mod.rs
index dae20ba..2f7375c 100644
--- a/src/invite/routes/mod.rs
+++ b/src/invite/routes/mod.rs
@@ -7,6 +7,8 @@ use crate::app::App;
mod invite;
mod post;
+#[cfg(test)]
+mod test;
pub fn router() -> Router<App> {
Router::new()
diff --git a/src/invite/routes/post.rs b/src/invite/routes/post.rs
index eb7d706..898081e 100644
--- a/src/invite/routes/post.rs
+++ b/src/invite/routes/post.rs
@@ -10,7 +10,7 @@ pub async fn handler(
identity: Identity,
_: Json<Request>,
) -> Result<Json<Invite>, Internal> {
- let invite = app.invites().create(&identity.login, &issued_at).await?;
+ let invite = app.invites().issue(&identity.login, &issued_at).await?;
Ok(Json(invite))
}
diff --git a/src/invite/routes/test.rs b/src/invite/routes/test.rs
new file mode 100644
index 0000000..4d99660
--- /dev/null
+++ b/src/invite/routes/test.rs
@@ -0,0 +1,28 @@
+use axum::extract::{Json, State};
+
+use super::post;
+use crate::test::fixtures;
+
+#[tokio::test]
+async fn create_invite() {
+ // Set up the environment
+
+ let app = fixtures::scratch_app().await;
+ let issuer = fixtures::identity::create(&app, &fixtures::now()).await;
+ let issued_at = fixtures::now();
+
+ // Call the endpoint
+
+ let Json(invite) = post::handler(
+ State(app),
+ issued_at.clone(),
+ issuer.clone(),
+ Json(post::Request {}),
+ )
+ .await
+ .expect("creating an invite always succeeds");
+
+ // Verify the response
+ assert_eq!(issuer.login.id, invite.issuer);
+ assert_eq!(&*issued_at, &invite.issued_at);
+}
diff --git a/src/test/fixtures/invite.rs b/src/test/fixtures/invite.rs
new file mode 100644
index 0000000..654d1b4
--- /dev/null
+++ b/src/test/fixtures/invite.rs
@@ -0,0 +1,17 @@
+use crate::{
+ app::App,
+ clock::DateTime,
+ invite::{self, Invite},
+ login::Login,
+};
+
+pub async fn issue(app: &App, issuer: &Login, issued_at: &DateTime) -> Invite {
+ app.invites()
+ .issue(issuer, issued_at)
+ .await
+ .expect("issuing invites never fails")
+}
+
+pub fn fictitious() -> invite::Id {
+ invite::Id::generate()
+}
diff --git a/src/test/fixtures/mod.rs b/src/test/fixtures/mod.rs
index 9111811..2b7b6af 100644
--- a/src/test/fixtures/mod.rs
+++ b/src/test/fixtures/mod.rs
@@ -7,6 +7,7 @@ pub mod cookie;
pub mod event;
pub mod future;
pub mod identity;
+pub mod invite;
pub mod login;
pub mod message;