diff options
| author | Elvis Claros Castro <elvis@claros.ar> | 2026-09-26 18:47:40 -0300 |
|---|---|---|
| committer | Elvis Claros Castro <elvis@claros.ar> | 2026-09-26 18:47:40 -0300 |
| commit | d9738b4be2add82ff955f061c79316b0dc91768f (patch) | |
| tree | e0f31bb9f72dff315fc475f9e9f30322b69602ff /tests/cli.rs | |
| download | posta-d9738b4be2add82ff955f061c79316b0dc91768f.tar.gz posta-d9738b4be2add82ff955f061c79316b0dc91768f.zip | |
Diffstat (limited to 'tests/cli.rs')
| -rw-r--r-- | tests/cli.rs | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/tests/cli.rs b/tests/cli.rs new file mode 100644 index 0000000..deca4ae --- /dev/null +++ b/tests/cli.rs @@ -0,0 +1,144 @@ +//! End-to-end CLI tests that don't need a mail server. + +use assert_cmd::Command; +use predicates::prelude::*; +use std::io::Write; + +fn posta() -> Command { + let mut cmd = Command::cargo_bin("posta").unwrap(); + // Isolate from the developer's real config and environment. + for (k, _) in std::env::vars() { + if k.starts_with("POSTA_") { + cmd.env_remove(k); + } + } + cmd +} + +fn write_config(dir: &tempfile::TempDir, contents: &str) -> std::path::PathBuf { + let path = dir.path().join("config.toml"); + let mut f = std::fs::File::create(&path).unwrap(); + f.write_all(contents.as_bytes()).unwrap(); + path +} + +const SAMPLE: &str = r#" +default_account = "personal" + +[accounts.personal] +email = "alice@example.com" +imap_url = "imap://alice@mail.example.com" +smtp_url = "smtp://alice@mail.example.com" +password = "x" + +[accounts.work] +email = "alice@work.example" +imap_url = "imaps://alice@imap.work.example" +"#; + +#[test] +fn help_mentions_the_basics() { + posta() + .arg("--help") + .assert() + .success() + .stdout(predicate::str::contains("IMAP/SMTP")) + .stdout(predicate::str::contains("send")) + .stdout(predicate::str::contains("list")); +} + +#[test] +fn version_prints_name_and_number() { + posta() + .arg("--version") + .assert() + .success() + .stdout(predicate::str::contains("posta")); +} + +#[test] +fn accounts_lists_names_without_secrets() { + let dir = tempfile::tempdir().unwrap(); + let cfg = write_config(&dir, SAMPLE); + posta() + .arg("--config") + .arg(&cfg) + .arg("accounts") + .assert() + .success() + .stdout(predicate::str::contains("personal")) + .stdout(predicate::str::contains("work")) + .stdout(predicate::str::contains("\"x\"").not()); +} + +#[test] +fn missing_config_file_is_a_clear_error() { + posta() + .env("POSTA_CONFIG", "/nonexistent/posta.toml") + .arg("status") + .assert() + .failure() + .stderr(predicate::str::contains("cannot read config file")); +} + +#[test] +fn unknown_account_error_lists_available_ones() { + let dir = tempfile::tempdir().unwrap(); + let cfg = write_config(&dir, SAMPLE); + posta() + .arg("--config") + .arg(&cfg) + .args(["--account", "nope", "status"]) + .assert() + .failure() + .stderr(predicate::str::contains("personal").and(predicate::str::contains("work"))); +} + +#[test] +fn invalid_toml_reports_the_file() { + let dir = tempfile::tempdir().unwrap(); + let cfg = write_config(&dir, "accounts = 42"); + posta() + .arg("--config") + .arg(&cfg) + .arg("status") + .assert() + .failure() + .stderr(predicate::str::contains("invalid config file")); +} + +#[test] +fn env_only_mode_needs_no_config_file() { + // No config file at all: endpoints come from the environment. The URL is + // parsed before any connection is attempted, so a bad one fails fast. + posta() + .env("POSTA_CONFIG", "/nonexistent/posta.toml") + .env_remove("POSTA_CONFIG") // ensure truly unset + .env("HOME", "/nonexistent-home") + .env("POSTA_IMAP_URL", "ftp://wrong") + .arg("status") + .assert() + .failure() + .stderr(predicate::str::contains("imap://")); +} + +#[test] +fn send_rejects_invalid_recipient_before_connecting() { + let dir = tempfile::tempdir().unwrap(); + let cfg = write_config(&dir, SAMPLE); + posta() + .arg("--config") + .arg(&cfg) + .args([ + "send", + "--to", + "not-an-address", + "--subject", + "hi", + "--body", + "x", + ]) + .assert() + .failure() + .stderr(predicate::str::contains("invalid recipient")); +} |