test: convert single test file to test suite
This commit is contained in:
parent
b61f02c03f
commit
da1a508616
5 changed files with 199 additions and 194 deletions
86
tests/api/helpers.rs
Normal file
86
tests/api/helpers.rs
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
use learn_axum::configuration::{get_configuration, DatabaseSettings};
|
||||
use learn_axum::email_client::EmailClient;
|
||||
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`
|
||||
static TRACING: Lazy<()> = Lazy::new(|| {
|
||||
let default_filter_level = "info".to_string();
|
||||
let subscriber_name = "test".to_string();
|
||||
// We cannot assign the output of `get_subscriber` to a variable based on the
|
||||
// value TEST_LOG` because the sink is part of the type returned by
|
||||
// `get_subscriber`, therefore they are not the same type. We could work around
|
||||
// it, but this is the most straight-forward way of moving forward.
|
||||
if std::env::var("TEST_LOG").is_ok() {
|
||||
let subscriber = get_subscriber(subscriber_name, default_filter_level, std::io::stdout);
|
||||
init_subscriber(subscriber);
|
||||
} else {
|
||||
let subscriber = get_subscriber(subscriber_name, default_filter_level, std::io::sink);
|
||||
init_subscriber(subscriber);
|
||||
};
|
||||
});
|
||||
|
||||
pub struct TestApp {
|
||||
pub address: String,
|
||||
pub db_pool: PgPool,
|
||||
}
|
||||
|
||||
pub async fn spawn_app() -> TestApp {
|
||||
// The first time `initialize` is invoked the code in `TRACING` is executed.
|
||||
// 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());
|
||||
|
||||
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;
|
||||
|
||||
// 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,
|
||||
);
|
||||
|
||||
let service = learn_axum::startup::app(connection_pool.clone(), email_client);
|
||||
tokio::spawn(async move {
|
||||
axum::serve(listener, service).await.unwrap();
|
||||
});
|
||||
TestApp {
|
||||
address,
|
||||
db_pool: connection_pool,
|
||||
}
|
||||
}
|
||||
|
||||
async fn configure_database(config: &DatabaseSettings) -> PgPool {
|
||||
// Create database
|
||||
let mut connection = PgConnection::connect_with(&config.without_db())
|
||||
.await
|
||||
.expect("Failed to connect to Postgres");
|
||||
connection
|
||||
.execute(format!(r#"CREATE DATABASE "{}";"#, config.name).as_str())
|
||||
.await
|
||||
.expect("Failed to create database.");
|
||||
|
||||
// Migrate database
|
||||
let connection_pool = PgPool::connect_with(config.with_db())
|
||||
.await
|
||||
.expect("Failed to connect to Postgres.");
|
||||
sqlx::migrate!("./migrations")
|
||||
.run(&connection_pool)
|
||||
.await
|
||||
.expect("Failed to migrate the database");
|
||||
|
||||
connection_pool
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue