🐸 Frogue(Fed)

~ololduck/Frogue

Raw

//! Migrations are bundled in the server and applied on startup.
//!
//! The server is spawned against a fresh database that has never seen the
//! migrator. Once it accepts connections - which `main` only does after the
//! database is ready - every bundled migration must be recorded as applied, so
//! nobody has to remember to run the `migration` CLI before starting the
//! server.

mod support;

use miette::IntoDiagnostic;
use migration::{Migrator, MigratorTrait};
use sea_orm::Database;
use support::{Server, free_port};

#[tokio::test]
async fn applies_migrations_on_startup() -> miette::Result<()> {
    let port = free_port();
    let mut server = Server::spawn(&format!("127.0.0.1:{port}"));
    // `main` only binds the listener once the database is ready, so a
    // successful connection means the migrations have run.
    server.wait_for_connection(port);

    let db = Database::connect(server.database_url())
        .await
        .into_diagnostic()?;

    // The read-only status check never creates the migration table, so a server
    // that did not migrate leaves every migration pending rather than passing
    // by accident.
    let pending = Migrator::get_pending_migrations_read_only(&db)
        .await
        .into_diagnostic()?;

    assert!(
        pending.is_empty(),
        "the server should have applied every migration, still pending: {:?}",
        pending.iter().map(|m| m.name()).collect::<Vec<_>>()
    );

    Ok(())
}