diff --git a/crates/comenqd/src/daemon.rs b/crates/comenqd/src/daemon.rs index 3c23254..e2095fc 100644 --- a/crates/comenqd/src/daemon.rs +++ b/crates/comenqd/src/daemon.rs @@ -245,7 +245,14 @@ pub async fn run_worker( mod tests { //! Tests for the daemon tasks. use super::*; + mod test_helpers { + include!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/../../tests/util/test_helpers.rs" + )); + } use tempfile::tempdir; + use test_helpers::{octocrab_for, temp_config}; use test_support::wait_for_file; use tokio::io::AsyncWriteExt; use tokio::net::{UnixListener, UnixStream}; @@ -256,12 +263,9 @@ mod tests { async fn setup_run_worker(status: u16) -> (MockServer, Arc, Receiver, Arc) { let dir = tempdir().expect("tempdir"); - let cfg = Arc::new(Config { - github_token: "t".into(), - socket_path: dir.path().join("sock"), - queue_path: dir.path().join("q"), - cooldown_period_seconds: 0, - }); + let mut c = temp_config(&dir); + c.cooldown_period_seconds = 0; + let cfg = Arc::new(c); let (sender, rx) = channel(&cfg.queue_path).expect("channel"); let req = CommentRequest { owner: "o".into(), @@ -281,14 +285,7 @@ mod tests { .mount(&server) .await; - let octo = Arc::new( - Octocrab::builder() - .personal_token("t".to_string()) - .base_uri(server.uri()) - .expect("base_uri") - .build() - .expect("build octocrab"), - ); + let octo = octocrab_for(&server); (server, cfg, rx, octo) } @@ -306,12 +303,7 @@ mod tests { #[tokio::test] async fn run_creates_queue_directory() { let dir = tempdir().expect("Failed to create temporary directory"); - let cfg = Config { - github_token: "t".into(), - socket_path: dir.path().join("sock"), - queue_path: dir.path().join("q"), - cooldown_period_seconds: 1, - }; + let cfg = temp_config(&dir); assert!(!cfg.queue_path.exists()); @@ -367,12 +359,7 @@ mod tests { #[tokio::test] async fn run_listener_accepts_connections() { let dir = tempdir().expect("tempdir"); - let cfg = Arc::new(Config { - github_token: "t".into(), - socket_path: dir.path().join("sock"), - queue_path: dir.path().join("q"), - cooldown_period_seconds: 1, - }); + let cfg = Arc::new(temp_config(&dir)); let (sender, mut receiver) = channel(&cfg.queue_path).expect("channel"); let (client_tx, writer_rx) = mpsc::unbounded_channel(); diff --git a/tests/cucumber.rs b/tests/cucumber.rs index cabfd77..b1f8f32 100644 --- a/tests/cucumber.rs +++ b/tests/cucumber.rs @@ -1,4 +1,5 @@ mod steps; +mod util; mod support; use cucumber::World as _; use steps::{ diff --git a/tests/steps/listener_steps.rs b/tests/steps/listener_steps.rs index d15309e..98c73da 100644 --- a/tests/steps/listener_steps.rs +++ b/tests/steps/listener_steps.rs @@ -12,6 +12,7 @@ use tokio::io::AsyncWriteExt; use tokio::net::UnixStream; use tokio::sync::{mpsc, watch}; +use crate::util::test_helpers::temp_config; use comenq_lib::CommentRequest; use comenqd::config::Config; use comenqd::daemon::{queue_writer, run_listener}; @@ -36,12 +37,7 @@ impl std::fmt::Debug for ListenerWorld { #[given("a running listener task")] async fn running_listener(world: &mut ListenerWorld) { let dir = TempDir::new().expect("tempdir"); - let cfg = Arc::new(Config { - github_token: String::from("t"), - socket_path: dir.path().join("sock"), - queue_path: dir.path().join("q"), - cooldown_period_seconds: 1, - }); + let cfg = Arc::new(temp_config(&dir)); let (sender, receiver) = channel(&cfg.queue_path).expect("channel"); let (client_tx, writer_rx) = mpsc::unbounded_channel(); let (shutdown_tx, shutdown_rx) = watch::channel(()); diff --git a/tests/steps/worker_steps.rs b/tests/steps/worker_steps.rs index 297e466..517304a 100644 --- a/tests/steps/worker_steps.rs +++ b/tests/steps/worker_steps.rs @@ -7,11 +7,11 @@ use std::sync::Arc; use std::time::Duration; +use crate::util::test_helpers::{octocrab_for, temp_config}; use comenq_lib::CommentRequest; use comenqd::config::Config; use comenqd::daemon::run_worker; use cucumber::{World, given, then, when}; -use octocrab::Octocrab; use tempfile::TempDir; use tokio::time::sleep; use wiremock::matchers::{method, path}; @@ -36,12 +36,9 @@ impl std::fmt::Debug for WorkerWorld { #[given("a queued comment request")] async fn queued_request(world: &mut WorkerWorld) { let dir = TempDir::new().expect("tempdir"); - let cfg = Arc::new(Config { - github_token: "t".into(), - socket_path: dir.path().join("sock"), - queue_path: dir.path().join("q"), - cooldown_period_seconds: 0, - }); + let mut cfg = temp_config(&dir); + cfg.cooldown_period_seconds = 0; + let cfg = Arc::new(cfg); let (mut sender, receiver) = channel(&cfg.queue_path).expect("channel"); let req = CommentRequest { owner: "o".into(), @@ -83,14 +80,7 @@ async fn worker_runs(world: &mut WorkerWorld) { let cfg = world.cfg.as_ref().unwrap().clone(); let rx = world.receiver.take().unwrap(); let server = world.server.as_ref().unwrap(); - let octocrab = Arc::new( - Octocrab::builder() - .personal_token("t".to_string()) - .base_uri(server.uri()) - .expect("base_uri") - .build() - .expect("build octocrab"), - ); + let octocrab = octocrab_for(server); let handle = tokio::spawn(async move { let _ = run_worker(cfg, rx, octocrab).await; }); diff --git a/tests/util/mod.rs b/tests/util/mod.rs new file mode 100644 index 0000000..a5b0ca8 --- /dev/null +++ b/tests/util/mod.rs @@ -0,0 +1,3 @@ +//! Test utility modules. + +pub mod test_helpers; diff --git a/tests/util/test_helpers.rs b/tests/util/test_helpers.rs new file mode 100644 index 0000000..8e90dcc --- /dev/null +++ b/tests/util/test_helpers.rs @@ -0,0 +1,59 @@ +//! Helper utilities for behavioural and unit tests. +//! +//! These functions create temporary daemon configuration objects and +//! Octocrab clients tailored for a `wiremock::MockServer`. + +use std::sync::Arc; + +use comenqd::config::Config; +use octocrab::Octocrab; +use tempfile::TempDir; +use wiremock::MockServer; + +/// Build a temporary [`Config`] using paths under `tmp`. +/// +/// # Examples +/// +/// ``` +/// use tempfile::tempdir; +/// use comenqd::config::Config; +/// use util::test_helpers::temp_config; +/// +/// let dir = tempdir().unwrap(); +/// let cfg: Config = temp_config(&dir); +/// assert!(cfg.socket_path.ends_with("sock")); +/// ``` +pub fn temp_config(tmp: &TempDir) -> Config { + Config { + github_token: String::from("t"), + socket_path: tmp.path().join("sock"), + queue_path: tmp.path().join("q"), + cooldown_period_seconds: 1, + } +} + +/// Create an [`Octocrab`] instance configured for `server`. +/// +/// # Examples +/// +/// ``` +/// use wiremock::MockServer; +/// use util::test_helpers::octocrab_for; +/// +/// # tokio_test::block_on(async { +/// let server = MockServer::start().await; +/// let octocrab = octocrab_for(&server); +/// assert!(octocrab.base_url().as_str().contains(&server.uri())); +/// # }); +/// ``` +#[expect(clippy::expect_used, reason = "simplify test helper setup")] +pub fn octocrab_for(server: &MockServer) -> Arc { + Arc::new( + Octocrab::builder() + .personal_token("t".to_string()) + .base_uri(server.uri()) + .expect("base_uri") + .build() + .expect("build octocrab"), + ) +}