Skip to content

Commit

Permalink
refactor: moving the integration tests to tests folder, and create st…
Browse files Browse the repository at this point in the history
…artup.rs containing all the boilerplate for spawning server
  • Loading branch information
m4salah committed Jan 6, 2024
1 parent c3b70c4 commit 2a5b398
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 136 deletions.
106 changes: 0 additions & 106 deletions src/handlers/day22.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,109 +143,3 @@ impl AdjacencyListGraph {
(((v1.0 - v2.0).pow(2) + (v1.1 - v2.1).pow(2) + (v1.2 - v2.2).pow(2)) as f32).sqrt()
}
}

#[cfg(test)]
mod tests {
use super::*;
use axum::{
body::Body,
http::{header, Method, Request, StatusCode},
};
use http_body_util::BodyExt;
use tower::ServiceExt; // for `call`, `oneshot`, and `ready`
use tracing_test::traced_test;

#[tokio::test]
#[traced_test]
async fn health_check() {
// Arrange
let app = router();

// Act
let response = app
.oneshot(
Request::builder()
.uri("/22/health")
.body(Body::empty())
.unwrap(),
)
.await
.unwrap();

// Assert
assert_eq!(response.status(), StatusCode::OK);
}

#[tokio::test]
#[traced_test]
async fn day22_integers() {
// Arrange
let app = router();

// Act
let response = app
.oneshot(
Request::builder()
.uri("/22/integers")
.method(Method::POST)
.header(header::CONTENT_TYPE, mime::APPLICATION_JSON.as_ref())
.body(Body::from(
r#"888
77
888
22
77"#,
))
.unwrap(),
)
.await
.unwrap();

// Assert
assert_eq!(response.status(), StatusCode::OK);
let body = response.into_body().collect().await.unwrap().to_bytes();
let body = String::from_utf8_lossy(&body[..]);
let expected = "🎁".repeat(22);
assert_eq!(body, expected);
}

#[tokio::test]
#[traced_test]
async fn day22_rocket() {
// Arrange
let app = router();

// Act
let response = app
.oneshot(
Request::builder()
.uri("/22/rocket")
.method(Method::POST)
.header(header::CONTENT_TYPE, mime::APPLICATION_JSON.as_ref())
.body(Body::from(
r#"5
0 1 0
-2 2 3
3 -3 -5
1 1 5
4 3 5
4
0 1
2 4
3 4
1 2
"#,
))
.unwrap(),
)
.await
.unwrap();

// Assert
assert_eq!(response.status(), StatusCode::OK);
let body = response.into_body().collect().await.unwrap().to_bytes();
let expected = "3 26.123";
let body = String::from_utf8_lossy(&body[..]);
assert_eq!(body, expected);
}
}
34 changes: 17 additions & 17 deletions src/handlers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
use sqlx::{Pool, Postgres};

mod day0;
mod day1;
mod day11;
mod day12;
mod day13;
mod day14;
mod day15;
mod day18;
mod day19;
mod day20;
mod day21;
mod day22;
mod day4;
mod day5;
mod day6;
mod day7;
mod day8;
pub mod day0;
pub mod day1;
pub mod day11;
pub mod day12;
pub mod day13;
pub mod day14;
pub mod day15;
pub mod day18;
pub mod day19;
pub mod day20;
pub mod day21;
pub mod day22;
pub mod day4;
pub mod day5;
pub mod day6;
pub mod day7;
pub mod day8;

pub fn router(pool: Pool<Postgres>, geocoding_api_key: String) -> axum::Router {
axum::Router::new()
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod config;
pub mod handlers;
pub mod startup;
21 changes: 8 additions & 13 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
use std::{error::Error, net::SocketAddr};

use axum::Router;
use clap::Parser;
use sqlx::{PgPool, Pool, Postgres};
use sqlx::PgPool;
use startup::run;
use tokio::signal;

mod config;
mod handlers;

fn app(pool: Pool<Postgres>, geocoding_api_key: String) -> Router {
handlers::router(pool, geocoding_api_key)
}
mod startup;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
Expand All @@ -34,15 +31,13 @@ async fn main() -> Result<(), Box<dyn Error>> {
// run our app with hyper, listening globally on port PORT
let listener = tokio::net::TcpListener::bind(&addr).await.unwrap();
tracing::info!("listening on {}", addr);
axum::serve(
listener,
app(pool, config.geocoding_api_key).into_make_service_with_connect_info::<SocketAddr>(),
)
.with_graceful_shutdown(shutdown_signal())
.await
.unwrap();

run(listener, pool, config)?
.with_graceful_shutdown(shutdown_signal())
.await?;
Ok(())
}

async fn shutdown_signal() {
let ctrl_c = async {
signal::ctrl_c()
Expand Down
32 changes: 32 additions & 0 deletions src/startup.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use axum::{
extract::{connect_info::IntoMakeServiceWithConnectInfo, ConnectInfo},
middleware::AddExtension,
serve::Serve,
Router,
};
use sqlx::{PgPool, Pool, Postgres};
use std::net::SocketAddr;
use tokio::net::TcpListener;

use crate::{config, handlers};

fn app(pool: Pool<Postgres>, geocoding_api_key: String) -> Router {
handlers::router(pool, geocoding_api_key)
}

type Server = Serve<
IntoMakeServiceWithConnectInfo<Router, SocketAddr>,
AddExtension<Router, ConnectInfo<SocketAddr>>,
>;

pub fn run(
listener: TcpListener,
db_pool: PgPool,
config: config::Config,
) -> Result<Server, std::io::Error> {
let server = axum::serve(
listener,
app(db_pool, config.geocoding_api_key).into_make_service_with_connect_info::<SocketAddr>(),
);
Ok(server)
}
100 changes: 100 additions & 0 deletions tests/day22.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
use axum::{
body::Body,
http::{header, Method, Request, StatusCode},
};
use cch23_challenge::handlers::day22::router;
use http_body_util::BodyExt;
use tower::ServiceExt; // for `call`, `oneshot`, and `ready`

// TODO: remove the coupling between the tests and axum service
// TODO: like this this example https://github.com/LukeMathWalker/zero-to-production/blob/root-chapter-03-part1/tests/health_check.rs
#[tokio::test]
async fn health_check() {
// Arrange
let app = router();

// Act
let response = app
.oneshot(
Request::builder()
.uri("/22/health")
.body(Body::empty())
.unwrap(),
)
.await
.unwrap();

// Assert
assert_eq!(response.status(), StatusCode::OK);
}

#[tokio::test]
async fn day22_integers() {
// Arrange
let app = router();

// Act
let response = app
.oneshot(
Request::builder()
.uri("/22/integers")
.method(Method::POST)
.header(header::CONTENT_TYPE, mime::APPLICATION_JSON.as_ref())
.body(Body::from(
r#"888
77
888
22
77"#,
))
.unwrap(),
)
.await
.unwrap();

// Assert
assert_eq!(response.status(), StatusCode::OK);
let body = response.into_body().collect().await.unwrap().to_bytes();
let body = String::from_utf8_lossy(&body[..]);
let expected = "🎁".repeat(22);
assert_eq!(body, expected);
}

#[tokio::test]
async fn day22_rocket() {
// Arrange
let app = router();

// Act
let response = app
.oneshot(
Request::builder()
.uri("/22/rocket")
.method(Method::POST)
.header(header::CONTENT_TYPE, mime::APPLICATION_JSON.as_ref())
.body(Body::from(
r#"5
0 1 0
-2 2 3
3 -3 -5
1 1 5
4 3 5
4
0 1
2 4
3 4
1 2
"#,
))
.unwrap(),
)
.await
.unwrap();

// Assert
assert_eq!(response.status(), StatusCode::OK);
let body = response.into_body().collect().await.unwrap().to_bytes();
let expected = "3 26.123";
let body = String::from_utf8_lossy(&body[..]);
assert_eq!(body, expected);
}

0 comments on commit 2a5b398

Please sign in to comment.