|
|
@@ -130,6 +130,47 @@ def test_config_invalid_mode_raises():
|
|
|
os.environ.pop("AGENTPAAS_DEPLOYMENT_MODE", None)
|
|
|
|
|
|
|
|
|
+def test_config_desktop_picks_visible_data_dir(tmp_path, monkeypatch):
|
|
|
+ """CR FR-002: desktop users need a discoverable, branded data dir
|
|
|
+ (`~/LambdAgentDesktop`), not a hidden `~/.agentpaas/data`. lab/paas
|
|
|
+ keep the hidden dir to follow OS convention."""
|
|
|
+ monkeypatch.delenv("AGENTPAAS_DATA_DIR", raising=False)
|
|
|
+ monkeypatch.setenv("AGENTPAAS_DEPLOYMENT_MODE", "desktop")
|
|
|
+ monkeypatch.setenv("HOME", str(tmp_path))
|
|
|
+ from agentpaas.config import AgentPaaSConfig
|
|
|
+ cfg = AgentPaaSConfig()
|
|
|
+ assert cfg.deployment_mode == "desktop"
|
|
|
+ assert cfg.data_dir.endswith("LambdAgentDesktop"), cfg.data_dir
|
|
|
+
|
|
|
+ monkeypatch.setenv("AGENTPAAS_DEPLOYMENT_MODE", "lab")
|
|
|
+ cfg2 = AgentPaaSConfig()
|
|
|
+ assert cfg2.deployment_mode == "lab"
|
|
|
+ assert cfg2.data_dir.endswith(".agentpaas/data"), cfg2.data_dir
|
|
|
+
|
|
|
+
|
|
|
+def test_config_default_host_is_loopback_for_non_paas(monkeypatch, tmp_path):
|
|
|
+ """Q12 + audit critical #1 same posture: desktop / lab default to
|
|
|
+ 127.0.0.1 (locked down). paas defaults to 0.0.0.0 (behind reverse
|
|
|
+ proxy in production). AGENTPAAS_HOST overrides in all cases."""
|
|
|
+ monkeypatch.delenv("AGENTPAAS_HOST", raising=False)
|
|
|
+ monkeypatch.setenv("HOME", str(tmp_path))
|
|
|
+ from agentpaas.config import AgentPaaSConfig
|
|
|
+
|
|
|
+ monkeypatch.setenv("AGENTPAAS_DEPLOYMENT_MODE", "desktop")
|
|
|
+ assert AgentPaaSConfig().host == "127.0.0.1"
|
|
|
+
|
|
|
+ monkeypatch.setenv("AGENTPAAS_DEPLOYMENT_MODE", "lab")
|
|
|
+ assert AgentPaaSConfig().host == "127.0.0.1"
|
|
|
+
|
|
|
+ monkeypatch.setenv("AGENTPAAS_DEPLOYMENT_MODE", "paas")
|
|
|
+ assert AgentPaaSConfig().host == "0.0.0.0"
|
|
|
+
|
|
|
+ # Explicit override wins in any mode (advanced user case).
|
|
|
+ monkeypatch.setenv("AGENTPAAS_HOST", "0.0.0.0")
|
|
|
+ monkeypatch.setenv("AGENTPAAS_DEPLOYMENT_MODE", "desktop")
|
|
|
+ assert AgentPaaSConfig().host == "0.0.0.0"
|
|
|
+
|
|
|
+
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
|
# Middleware: desktop blocks /admin /billing → 404 (Q9 oracle defense)
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
|
@@ -207,6 +248,54 @@ def test_paas_mode_does_not_block_billing(client, db):
|
|
|
assert r.status_code != 404
|
|
|
|
|
|
|
|
|
+# ─────────────────────────────────────────────────────────────────────────────
|
|
|
+# /api/v1/setup/mode — Q8 chip endpoint (unauthenticated)
|
|
|
+# ─────────────────────────────────────────────────────────────────────────────
|
|
|
+
|
|
|
+def test_setup_mode_endpoint_no_auth_required(client, db):
|
|
|
+ """Q8: the mode chip renders BEFORE login (so the first-run wizard
|
|
|
+ can adapt). /setup/mode must be reachable without a Bearer."""
|
|
|
+ r = client.get("/api/v1/setup/mode")
|
|
|
+ assert r.status_code == 200, r.text[:200]
|
|
|
+ body = r.json()
|
|
|
+ assert "mode" in body and body["mode"] in ("desktop", "lab", "paas")
|
|
|
+ assert "tenant_alias" in body
|
|
|
+ assert "bootstrapped" in body
|
|
|
+
|
|
|
+
|
|
|
+def test_setup_mode_reflects_current_deployment_mode(client, db, mode):
|
|
|
+ """Same client, different settings.deployment_mode → endpoint reports
|
|
|
+ the current value (no caching)."""
|
|
|
+ settings.deployment_mode = "paas"
|
|
|
+ assert client.get("/api/v1/setup/mode").json()["mode"] == "paas"
|
|
|
+
|
|
|
+ settings.deployment_mode = "lab"
|
|
|
+ assert client.get("/api/v1/setup/mode").json()["mode"] == "lab"
|
|
|
+
|
|
|
+ settings.deployment_mode = "desktop"
|
|
|
+ assert client.get("/api/v1/setup/mode").json()["mode"] == "desktop"
|
|
|
+
|
|
|
+
|
|
|
+def test_setup_mode_reports_bootstrapped_false_on_fresh_install(client, db, tmp_path):
|
|
|
+ """Fresh DB + no config file → bootstrapped=false. The first-run
|
|
|
+ wizard depends on this signal to know whether to render itself.
|
|
|
+
|
|
|
+ We have to patch CONFIG_FILE because the developer's real
|
|
|
+ ~/.agentpaas/config.json may already contain an api_key from a real
|
|
|
+ install; without the patch this test would assert against that
|
|
|
+ file's contents."""
|
|
|
+ from agentpaas.api.v1 import setup as setup_mod
|
|
|
+ original = setup_mod.CONFIG_FILE
|
|
|
+ setup_mod.CONFIG_FILE = str(tmp_path / "config.json")
|
|
|
+ try:
|
|
|
+ r = client.get("/api/v1/setup/mode")
|
|
|
+ body = r.json()
|
|
|
+ assert body["bootstrapped"] is False
|
|
|
+ assert body["tenant_alias"] == ""
|
|
|
+ finally:
|
|
|
+ setup_mod.CONFIG_FILE = original
|
|
|
+
|
|
|
+
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
|
# auto_bootstrap_desktop — Q11 tenant_id naming + idempotency
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|