diff --git a/tests/api/health_check.rs b/tests/api/health_check.rs index 70cec18..5b32d70 100644 --- a/tests/api/health_check.rs +++ b/tests/api/health_check.rs @@ -1,18 +1,12 @@ -use crate::helpers::{spawn_app, url}; +use crate::helpers::TestApp; #[tokio::test] async fn health_check_works() { // given - let client = reqwest::Client::new(); - let app = spawn_app().await; - let url = url(app.address, "health_check"); + let app = TestApp::spawn().await; // when - let response = client - .get(url) - .send() - .await - .expect("Failed to execute request"); + let response = app.get_health_check().await; // then assert!(response.status().is_success()); diff --git a/tests/api/helpers.rs b/tests/api/helpers.rs index dadb101..ed93556 100644 --- a/tests/api/helpers.rs +++ b/tests/api/helpers.rs @@ -1,4 +1,5 @@ use once_cell::sync::Lazy; +use reqwest::{Client, Response}; use sqlx::{Connection, Executor, PgConnection, PgPool}; use std::net::SocketAddr; use uuid::Uuid; @@ -20,33 +21,56 @@ static TRACING: Lazy<()> = Lazy::new(|| { } }); +static FAILED_TO_EXECUTE_REQUEST: &'static str = "Failed to execute request"; + pub struct TestApp { pub address: SocketAddr, pub db_pool: PgPool, + client: Client, } -pub async fn spawn_app() -> TestApp { - Lazy::force(&TRACING); +impl TestApp { + pub async fn spawn() -> Self { + Lazy::force(&TRACING); - let mut config = get_configuration().expect("Failed to read configuration"); - config.database.database_name = Uuid::new_v4().to_string(); - config.application.port = 0; + let mut config = get_configuration().expect("Failed to read configuration"); + config.database.database_name = Uuid::new_v4().to_string(); + config.application.port = 0; - let db_pool = configure_database(&config.database).await; - let app = Application::build(config).await; + let db_pool = configure_database(&config.database).await; + let app = Application::build(config).await; + let address = app.local_addr(); - let test_app = TestApp { - address: app.local_addr(), - db_pool, - }; + tokio::spawn(app.run_until_stopped()); - tokio::spawn(app.run_until_stopped()); + Self { + address, + db_pool, + client: Client::new(), + } + } - test_app -} + pub async fn get_health_check(&self) -> Response { + self.client + .get(self.url("/health_check")) + .send() + .await + .expect(FAILED_TO_EXECUTE_REQUEST) + } -pub fn url(addr: SocketAddr, endpoint: &str) -> String { - format!("http://{}/{}", addr, endpoint) + pub async fn post_subscriptions(&self, body: String) -> Response { + self.client + .post(self.url("/subscriptions")) + .header("Content-Type", "application/x-www-form-urlencoded") + .body(body) + .send() + .await + .expect(FAILED_TO_EXECUTE_REQUEST) + } + + fn url(&self, endpoint: &str) -> String { + format!("http://{}{endpoint}", self.address) + } } async fn configure_database(configuration: &DatabaseSettings) -> PgPool { diff --git a/tests/api/subscriptions.rs b/tests/api/subscriptions.rs index a78a572..bfb6ada 100644 --- a/tests/api/subscriptions.rs +++ b/tests/api/subscriptions.rs @@ -1,21 +1,13 @@ -use crate::helpers::{spawn_app, url}; +use crate::helpers::TestApp; #[tokio::test] async fn subscribe_returns_a_200_for_valid_form_data() { // given - let client = reqwest::Client::new(); + let app = TestApp::spawn().await; let body = "name=Imi%C4%99%20Nazwisko&email=imie.nazwisko%40example.com"; - let app = spawn_app().await; - let url = url(app.address, "subscriptions"); // when - let response = client - .post(url) - .header("Content-Type", "application/x-www-form-urlencoded") - .body(body) - .send() - .await - .expect("Failed to execute request"); + let response = app.post_subscriptions(body.into()).await; // then assert_eq!(response.status(), 200); @@ -30,9 +22,7 @@ async fn subscribe_returns_a_200_for_valid_form_data() { #[tokio::test] async fn subscribe_returns_a_400_when_fields_are_present_but_empty() { // given - let client = reqwest::Client::new(); - let app = spawn_app().await; - let url = url(app.address, "subscriptions"); + let app = TestApp::spawn().await; let test_cases = vec![ ("name=Imi%C4%99%20Nazwisko&email=", "empty email"), ( @@ -45,13 +35,7 @@ async fn subscribe_returns_a_400_when_fields_are_present_but_empty() { for (body, description) in test_cases { // when - let response = client - .post(&url) - .header("Content-Type", "application/x-www-form-urlencoded") - .body(body) - .send() - .await - .expect("Failed to execute request"); + let response = app.post_subscriptions(body.into()).await; // then assert_eq!( @@ -66,9 +50,7 @@ async fn subscribe_returns_a_400_when_fields_are_present_but_empty() { #[tokio::test] async fn subscribe_returns_a_400_when_data_is_missing() { // given - let client = reqwest::Client::new(); - let app = spawn_app().await; - let url = url(app.address, "subscriptions"); + let app = TestApp::spawn().await; let test_cases = vec![ ("name=Imi%C4%99%20Nazwisko", "missing the email"), ("email=imie.nazwisko%40example.com", "missing the name"), @@ -77,13 +59,7 @@ async fn subscribe_returns_a_400_when_data_is_missing() { for (body, message) in test_cases { // when - let response = client - .post(&url) - .header("Content-Type", "application/x-www-form-urlencoded") - .body(body) - .send() - .await - .expect("Failed to execute request"); + let response = app.post_subscriptions(body.into()).await; // then assert_eq!(