use axum::{body::Body, http::Request}; use sqlx::postgres::PgConnection; use sqlx::Connection; use std::net::{SocketAddr, TcpListener}; use tokio::task::JoinHandle; use ztp::*; type NullHandle = JoinHandle<()>; async fn spawn_server() -> (SocketAddr, NullHandle) { let configuration = ztp::configuration::get_configuration().unwrap(); let listener = TcpListener::bind("127.0.0.1:0".parse::().unwrap()).unwrap(); let addr = listener.local_addr().unwrap(); let handle: NullHandle = tokio::spawn(async move { axum::Server::from_tcp(listener) .unwrap() .serve(app(&configuration).await.into_make_service()) .await .unwrap(); }); (addr, handle) } #[tokio::test] async fn valid_subscription() { let (addr, _server_handle) = spawn_server().await; let body = "name=le%20guin&email=ursula_le_guin%40gmail.com"; let configuration = ztp::configuration::get_configuration().unwrap(); let mut connection = PgConnection::connect(&configuration.database.url()) .await .expect("Failed to connect to Postgres."); sqlx::query!("DELETE FROM subscriptions") .execute(&mut connection) .await .expect("Failed to clear out the subscriptions table"); let response = hyper::Client::new() .request( Request::builder() .method("POST") .header("content-type", "application/x-www-form-urlencoded") .uri(format!("http://{}/subscriptions", addr)) .body(Body::from(body)) .unwrap(), ) .await .expect("Failed to execute request."); // Assert assert_eq!(200, response.status().as_u16()); let saved = sqlx::query!("SELECT email, name FROM subscriptions",) .fetch_one(&mut connection) .await .expect("Failed to fetch saved subscription."); assert_eq!(saved.email, "ursula_le_guin@gmail.com"); assert_eq!(saved.name, "le guin"); sqlx::query!("DELETE FROM subscriptions") .execute(&mut connection) .await .expect("Failed to clear out the subscriptions table"); }