feat(docs): save chat answers as docs — edit screen, commit + push to the .env docs branch
This commit is contained in:
@@ -279,3 +279,121 @@ def test_effective_api_key_fallback(monkeypatch) -> None:
|
||||
monkeypatch.setenv("AIPI_KEY", "sk-from-env")
|
||||
s2 = _settings()
|
||||
assert s2.effective_api_key == "sk-from-env"
|
||||
|
||||
|
||||
# --- Docs push (phase 59) ---
|
||||
|
||||
|
||||
def test_docs_push_defaults_are_inert() -> None:
|
||||
"""Phase 59, D3: no docs repo by default — the feature is
|
||||
inert-by-default (button hidden, push endpoint 409s — the
|
||||
optional-feature pattern of the git-sources env fallback), and the
|
||||
branch/base defaults + raw work-dir string are in place."""
|
||||
s = _settings()
|
||||
assert s.docs_repo == ""
|
||||
assert s.docs_configured is False
|
||||
assert s.docs_branch == "bor-docs"
|
||||
assert s.docs_base_branch == "main"
|
||||
# Raw string on purpose — Path.expanduser() is applied by the push
|
||||
# service, not the setting (the sources_dir/upload_dir convention).
|
||||
assert s.docs_work_dir == "~/bor-docs"
|
||||
|
||||
|
||||
def test_docs_repo_set_is_configured(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
"""A non-empty ``BOR_DOCS_REPO`` turns the feature on — a URL or a
|
||||
local path (D3: generic remote, no scheme parsing here)."""
|
||||
for repo in ("/path/to/docs-repo", "https://git.example.com/docs.git"):
|
||||
monkeypatch.setenv("BOR_DOCS_REPO", repo)
|
||||
s = _settings()
|
||||
assert s.docs_configured is True
|
||||
assert s.docs_repo == repo
|
||||
# Whitespace-only behaves like empty: still inert.
|
||||
monkeypatch.setenv("BOR_DOCS_REPO", " ")
|
||||
assert _settings().docs_configured is False
|
||||
|
||||
|
||||
def test_docs_branch_env_override(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.delenv("BOR_DOCS_BRANCH", raising=False)
|
||||
monkeypatch.delenv("BOR_DOCS_BASE_BRANCH", raising=False)
|
||||
assert _settings().docs_branch == "bor-docs"
|
||||
assert _settings().docs_base_branch == "main"
|
||||
monkeypatch.setenv("BOR_DOCS_BRANCH", "docs-pr")
|
||||
monkeypatch.setenv("BOR_DOCS_BASE_BRANCH", "master")
|
||||
s = _settings()
|
||||
assert s.docs_branch == "docs-pr"
|
||||
assert s.docs_base_branch == "master"
|
||||
|
||||
|
||||
def test_docs_work_dir_env_override_is_raw_string(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setenv("BOR_DOCS_WORK_DIR", "/data/bor/docs")
|
||||
s = _settings()
|
||||
assert s.docs_work_dir == "/data/bor/docs"
|
||||
|
||||
|
||||
def test_docs_branch_whitespace_fails_loudly_when_repo_set(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
"""A whitespace-bearing branch would corrupt a ``git checkout``
|
||||
argument — fail loud at startup, naming the field (the
|
||||
``agent_max_rounds`` pattern)."""
|
||||
monkeypatch.setenv("BOR_DOCS_REPO", "/path/to/docs-repo")
|
||||
monkeypatch.setenv("BOR_DOCS_BRANCH", "bor docs")
|
||||
with pytest.raises(ValidationError, match="docs_branch"):
|
||||
_settings()
|
||||
|
||||
|
||||
def test_docs_branch_dotdot_fails_loudly_when_repo_set(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
"""``..`` is a path-traversal token, never part of a branch name.
|
||||
A blank branch is rejected too (empty while a repo is set)."""
|
||||
monkeypatch.setenv("BOR_DOCS_REPO", "/path/to/docs-repo")
|
||||
monkeypatch.setenv("BOR_DOCS_BRANCH", "a..b")
|
||||
with pytest.raises(ValidationError, match="docs_branch"):
|
||||
_settings()
|
||||
monkeypatch.setenv("BOR_DOCS_BRANCH", " ")
|
||||
with pytest.raises(ValidationError, match="docs_branch"):
|
||||
_settings()
|
||||
|
||||
|
||||
def test_docs_base_branch_invalid_fails_loudly_naming_field(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
"""The base branch gets the same token shape check — the error
|
||||
names ``docs_base_branch``, not the sibling field."""
|
||||
monkeypatch.setenv("BOR_DOCS_REPO", "/path/to/docs-repo")
|
||||
monkeypatch.setenv("BOR_DOCS_BASE_BRANCH", "bad branch")
|
||||
with pytest.raises(ValidationError, match="docs_base_branch"):
|
||||
_settings()
|
||||
monkeypatch.setenv("BOR_DOCS_BASE_BRANCH", "a..b")
|
||||
with pytest.raises(ValidationError, match="docs_base_branch"):
|
||||
_settings()
|
||||
|
||||
|
||||
def test_docs_branchs_valid_when_repo_set(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
"""Repo set + well-formed branch tokens boot cleanly and the
|
||||
feature is configured (dash/dot/slash branch names are legal git
|
||||
refs and stay accepted)."""
|
||||
monkeypatch.setenv("BOR_DOCS_REPO", "/path/to/docs-repo")
|
||||
s = _settings() # defaults bor-docs / main
|
||||
assert s.docs_configured is True
|
||||
monkeypatch.setenv("BOR_DOCS_BRANCH", "feature/docs-update")
|
||||
monkeypatch.setenv("BOR_DOCS_BASE_BRANCH", "develop")
|
||||
s2 = _settings()
|
||||
assert s2.docs_configured is True
|
||||
assert s2.docs_branch == "feature/docs-update"
|
||||
assert s2.docs_base_branch == "develop"
|
||||
|
||||
|
||||
def test_docs_branchs_garbage_ignored_when_repo_unset(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
"""All-or-nothing: while the repo is empty the feature is inert, so
|
||||
the (ignored) branch values must NOT block startup — only a
|
||||
configured repo makes the shape check apply."""
|
||||
monkeypatch.delenv("BOR_DOCS_REPO", raising=False)
|
||||
monkeypatch.setenv("BOR_DOCS_BRANCH", "bor docs..")
|
||||
monkeypatch.setenv("BOR_DOCS_BASE_BRANCH", "..")
|
||||
s = _settings()
|
||||
assert s.docs_configured is False
|
||||
assert s.docs_branch == "bor docs.." # stored verbatim, never used
|
||||
|
||||
Reference in New Issue
Block a user