refactor: remove code duplications for main and testing

This commit is contained in:
Sandro Eiler 2024-03-03 21:48:44 +01:00
parent da1a508616
commit ebd7755731
6 changed files with 143 additions and 114 deletions

View file

@ -1,9 +1,8 @@
use learn_axum::configuration::{get_configuration, DatabaseSettings};
use learn_axum::email_client::EmailClient;
use learn_axum::startup::{get_connection_pool, Application};
use learn_axum::telemetry::{get_subscriber, init_subscriber};
use once_cell::sync::Lazy;
use sqlx::{Connection, Executor, PgConnection, PgPool};
use tokio::net::TcpListener;
use uuid::Uuid;
/// Ensure that the `tracing` stack is only initialised once using `once_cell`
@ -33,33 +32,41 @@ pub async fn spawn_app() -> TestApp {
// All other invocations will instead skip execution.
Lazy::force(&TRACING);
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
let address = format!("http://{}", listener.local_addr().unwrap());
// TODO:
// // Launch a mock server to stand in for Postmark's API
// let email_server = MockServer::start().await;
let mut configuration = get_configuration().expect("Failed to read configuration.");
configuration.database.name = Uuid::new_v4().to_string();
let connection_pool = configure_database(&configuration.database).await;
// Randomise configuration to ensure test isolation
let configuration = {
let mut c = get_configuration().expect("Failed to read configuration.");
// Use a different database for each test case
c.database.name = Uuid::new_v4().to_string();
// Use a random OS port
c.application.port = 0;
c
};
// TODO: remove code duplication
let sender_email = configuration
.email_client
.sender()
.expect("Invalid sender email address.");
let timeout = configuration.email_client.timeout();
let email_client = EmailClient::new(
configuration.email_client.base_url,
sender_email,
configuration.email_client.authorization_token,
timeout,
);
// Create and migrate the database
configure_database(&configuration.database).await;
let connection_pool = get_connection_pool(&configuration.database);
let application = Application::build(configuration.clone())
.await
.expect("Failed to build application.");
// Get the port before spawning the application
let address = format!("http://127.0.0.1:{}", application.port());
// Launch the application as a background task
tokio::spawn(async move { application.run().await.expect("Failed to run the server") });
let service = learn_axum::startup::app(connection_pool.clone(), email_client);
tokio::spawn(async move {
axum::serve(listener, service).await.unwrap();
});
TestApp {
address,
// address: format!("http://localhost:{}", application_port),
// port: application_port,
db_pool: connection_pool,
// email_server,
// test_user: TestUser::generate(),
// api_client: client,
// email_client: configuration.email_client.client(),
}
}