Initial import of cf-temp-email deploy CLI

This commit is contained in:
mmc
2026-03-26 08:06:02 +08:00
commit 4100e9cf72
29 changed files with 6703 additions and 0 deletions

160
tests/test_config.py Normal file
View File

@@ -0,0 +1,160 @@
from __future__ import annotations
from pathlib import Path
import pytest
from cf_temp_email_deploy.config import (
apply_overrides,
default_config_document,
load_config,
parse_toml_value,
save_toml_document,
save_state,
set_dotted_value,
)
from cf_temp_email_deploy.errors import ConfigError
from cf_temp_email_deploy.models import DeploymentState
def test_parse_toml_value_supports_structured_literals() -> None:
assert parse_toml_value('"abc"') == "abc"
assert parse_toml_value("true") is True
assert parse_toml_value("[1, 2, 3]") == [1, 2, 3]
assert parse_toml_value("plain-text") == "plain-text"
def test_apply_overrides_and_load_config(tmp_path: Path) -> None:
document = default_config_document()
apply_overrides(
document,
{
"cloudflare.zone_name": "example.org",
"mail.domains": ["mail.example.org"],
"worker.vars.PREFIX": "custom",
},
)
config_path = tmp_path / "config.toml"
save_toml_document(config_path, document)
config = load_config(config_path)
assert config.cloudflare.zone_name == "example.org"
assert config.mail.domains == ["mail.example.org"]
assert config.worker.vars["PREFIX"] == "custom"
assert config.derived_worker_vars()["DOMAINS"] == ["mail.example.org"]
assert config.derived_worker_vars()["DISABLE_ANONYMOUS_USER_CREATE_EMAIL"] is True
assert config.source.repo_ref == ""
def test_default_config_marks_jwt_secret_optional() -> None:
document = default_config_document()
assert document["worker"]["secrets"]["JWT_SECRET"] == ""
def test_default_config_includes_user_access_and_linuxdo_sections() -> None:
document = default_config_document()
assert document["user_access"]["require_login_to_create"] is True
assert document["user_access"]["allow_user_register"] is False
assert document["linuxdo"]["linuxdo_oauth"] is False
assert document["linuxdo"]["client_id"] == ""
assert document["linuxdo"]["client_secret"] == ""
def test_load_config_requires_linuxdo_credentials_when_oauth_enabled(tmp_path: Path) -> None:
document = default_config_document()
document["linuxdo"]["linuxdo_oauth"] = True
document["linuxdo"]["client_id"] = ""
document["linuxdo"]["client_secret"] = ""
config_path = tmp_path / "config.toml"
save_toml_document(config_path, document)
with pytest.raises(ConfigError, match="linuxdo.client_id"):
load_config(config_path)
def test_load_config_requires_admin_passwords(tmp_path: Path) -> None:
document = default_config_document()
document["worker"]["vars"]["ADMIN_PASSWORDS"] = []
config_path = tmp_path / "config.toml"
save_toml_document(config_path, document)
with pytest.raises(ConfigError, match="ADMIN_PASSWORDS"):
load_config(config_path)
def test_load_config_requires_worker_domain_or_workers_dev(tmp_path: Path) -> None:
document = default_config_document()
document["worker"]["use_workers_dev"] = False
document["worker"]["custom_domain"] = ""
config_path = tmp_path / "config.toml"
save_toml_document(config_path, document)
with pytest.raises(ConfigError, match="worker.custom_domain"):
load_config(config_path)
def test_load_config_merges_selected_profile(tmp_path: Path) -> None:
document = default_config_document()
document["cloudflare"]["zone_name"] = "base.example.com"
document["mail"]["domains"] = ["base.example.com"]
document["pages"]["custom_domain"] = "app.base.example.com"
document["profiles"] = {
"account_b": {
"cloudflare": {
"account_id": "acc-b",
"zone_name": "kotei.asia",
"api_token": "token-b",
},
"mail": {"domains": ["mail.kotei.asia", "maila.kotei.asia"]},
"pages": {"custom_domain": "email.kotei.asia"},
}
}
config_path = tmp_path / "config.toml"
save_toml_document(config_path, document)
config = load_config(config_path, profile="account_b")
assert config.cloudflare.account_id == "acc-b"
assert config.cloudflare.zone_name == "kotei.asia"
assert config.mail.domains == ["mail.kotei.asia", "maila.kotei.asia"]
assert config.pages.custom_domain == "email.kotei.asia"
def test_load_config_rejects_missing_profile(tmp_path: Path) -> None:
config_path = tmp_path / "config.toml"
save_toml_document(config_path, default_config_document())
with pytest.raises(ConfigError, match="未找到 profile"):
load_config(config_path, profile="missing")
def test_set_dotted_value_rejects_scalar_parent() -> None:
document = default_config_document()
set_dotted_value(document, "cloudflare.account_id", "abc")
try:
set_dotted_value(document, "cloudflare.account_id.value", "x")
except Exception as exc: # pragma: no cover - narrow assertion below
assert "父节点不是表" in str(exc)
else: # pragma: no cover
raise AssertionError("expected parent table validation failure")
def test_save_state_roundtrip(tmp_path: Path) -> None:
state_path = tmp_path / ".deploy" / "state.toml"
state = DeploymentState()
state.mark_checkpoint("environment_checked")
state.worker.script_name = "worker-a"
state.worker.workers_dev_url = "https://worker-a.example.workers.dev"
save_state(state_path, state)
loaded_text = state_path.read_text(encoding="utf-8")
assert "environment_checked" in loaded_text
assert "worker-a" in loaded_text