From f2880eecd6d30f026def2229e9c1d89d7fddbee3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Eppl=C3=A9e?= Date: Tue, 26 Dec 2023 14:29:13 +0100 Subject: [PATCH] Add simple test with sqlx integration --- .github/workflows/ci.yml | 23 ++++++++++++++++++++--- Cargo.lock | 1 + Cargo.toml | 3 +++ Justfile | 19 +++++++++++++------ src/cli.rs | 3 ++- src/lib.rs | 2 +- src/server.rs | 10 ++++++---- tests/index.rs | 17 +++++++++++++++++ 8 files changed, 63 insertions(+), 15 deletions(-) create mode 100644 tests/index.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eec5367..2492f35 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,19 @@ jobs: name: CI runs-on: ubuntu-latest + services: + postgres: + image: postgres:16 + env: + POSTGRES_PASSWORD: postgres + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 5432:5432 + steps: - name: Checkout code uses: actions/checkout@v3 @@ -19,12 +32,16 @@ jobs: - name: cargo build run: cargo build - - - name: cargo test - run: cargo test + env: + SQLX_OFFLINE: true - name: cargo fmt run: cargo fmt --all -- --check - name: cargo clippy run: cargo clippy -- -D warnings + + - name: cargo test + run: cargo test + env: + DATABASE_URL: postgres://postgres:postgres@localhost:5432/linkblocks diff --git a/Cargo.lock b/Cargo.lock index c6369d9..a9137bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -971,6 +971,7 @@ dependencies = [ "railwind", "sqlx", "tokio", + "tower", "tower-http", "tracing", "tracing-subscriber", diff --git a/Cargo.toml b/Cargo.toml index 9106c8d..31784e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,3 +23,6 @@ tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } [build-dependencies] railwind = "0.1.5" walkdir = "2" + +[dev-dependencies] +tower = { version = "0.4.13", features = ["util"] } diff --git a/Justfile b/Justfile index 7f60f2d..81fc68e 100644 --- a/Justfile +++ b/Justfile @@ -19,18 +19,25 @@ start-database: exit fi - podman run \ - --name linkblocks_postgres --detach \ - --health-cmd pg_isready --health-interval 10s \ - -e POSTGRES_HOST_AUTH_METHOD=trust -e POSTGRES_DB=linkblocks \ - -p ${DATABASE_PORT}:5432 docker.io/postgres:16 \ - postgres + if ! podman inspect linkblocks_postgres &> /dev/null; then + podman create \ + --name linkblocks_postgres --detach \ + --health-cmd pg_isready --health-interval 10s \ + -e POSTGRES_HOST_AUTH_METHOD=trust -e POSTGRES_DB=linkblocks \ + -p ${DATABASE_PORT}:5432 docker.io/postgres:16 \ + postgres + fi + + podman start linkblocks_postgres for i in {1..20}; do pg_isready -h localhost -p $DATABASE_PORT && break sleep 1 done +stop-database: + podman stop linkblocks_postgres + test: cargo test diff --git a/src/cli.rs b/src/cli.rs index 27192f7..37f29cf 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -51,7 +51,8 @@ pub async fn run() -> Result<()> { } => { let pool = db::pool(&database_url).await?; db::migrate(&pool).await?; - server::start(listen_address, pool).await + let app = server::app(pool); + server::start(listen_address, app).await } } } diff --git a/src/lib.rs b/src/lib.rs index c89385a..eaac29c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,4 +2,4 @@ mod app_error; pub mod cli; mod db; mod routes; -mod server; +pub mod server; diff --git a/src/server.rs b/src/server.rs index ac1d284..2241bfc 100644 --- a/src/server.rs +++ b/src/server.rs @@ -6,8 +6,8 @@ use axum::{debug_handler, routing::get, Router}; use listenfd::ListenFd; use tower_http::trace::TraceLayer; -pub async fn start(listen: ListenArgs, pool: sqlx::PgPool) -> anyhow::Result<()> { - let app = Router::new() +pub fn app(pool: sqlx::PgPool) -> Router { + Router::new() .route("/", get(hello)) .route("/htmx-fragment", get(htmx_fragment)) .route( @@ -16,8 +16,10 @@ pub async fn start(listen: ListenArgs, pool: sqlx::PgPool) -> anyhow::Result<()> ) .route("/assets/*path", get(routes::assets::assets)) .layer(TraceLayer::new_for_http()) - .with_state(pool); + .with_state(pool) +} +pub async fn start(listen: ListenArgs, app: Router) -> anyhow::Result<()> { let listener = if let Some(listen_address) = listen.listen { tokio::net::TcpListener::bind(format!("{listen_address}")).await? } else { @@ -31,7 +33,7 @@ pub async fn start(listen: ListenArgs, pool: sqlx::PgPool) -> anyhow::Result<()> let listening_on = listener.local_addr()?; tracing::info!("Listening on http://{listening_on}"); - axum::serve(listener, app).await?; + axum::serve(listener, app); Ok(()) } diff --git a/tests/index.rs b/tests/index.rs new file mode 100644 index 0000000..b3ddb60 --- /dev/null +++ b/tests/index.rs @@ -0,0 +1,17 @@ +use axum::{ + body::Body, + http::{Request, StatusCode}, +}; +use sqlx::{Pool, Postgres}; +use tower::ServiceExt; // for `call`, `oneshot`, and `ready` +#[sqlx::test] +async fn index(pool: Pool) { + let app = linkblocks::server::app(pool); + + let response = app + .oneshot(Request::builder().uri("/").body(Body::empty()).unwrap()) + .await + .unwrap(); + + assert_eq!(response.status(), StatusCode::OK); +}