import json from furtka.cli import main def _set_env(monkeypatch, tmp_path): monkeypatch.setenv("FURTKA_APPS_DIR", str(tmp_path)) def test_app_list_empty(tmp_path, monkeypatch, capsys): _set_env(monkeypatch, tmp_path) rc = main(["app", "list"]) assert rc == 0 assert "no apps installed" in capsys.readouterr().out def test_app_list_json_empty(tmp_path, monkeypatch, capsys): _set_env(monkeypatch, tmp_path) rc = main(["app", "list", "--json"]) assert rc == 0 assert json.loads(capsys.readouterr().out) == [] def test_app_list_json_with_one_app(tmp_path, monkeypatch, capsys): _set_env(monkeypatch, tmp_path) app = tmp_path / "fileshare" app.mkdir() (app / "manifest.json").write_text( json.dumps( { "name": "fileshare", "display_name": "Network Files", "version": "0.1.0", "description": "SMB", "description_long": "Long description here.", "volumes": ["files"], "ports": [445], "icon": "icon.svg", "open_url": "smb://{host}/files", "settings": [ { "name": "SMB_USER", "label": "User", "description": "SMB user", "type": "text", "default": "furtka", "required": True, } ], } ) ) rc = main(["app", "list", "--json"]) assert rc == 0 data = json.loads(capsys.readouterr().out) assert len(data) == 1 assert data[0]["ok"] is True m = data[0]["manifest"] assert m["name"] == "fileshare" assert m["description_long"] == "Long description here." assert m["open_url"] == "smb://{host}/files" assert len(m["settings"]) == 1 assert m["settings"][0]["name"] == "SMB_USER" assert m["settings"][0]["required"] is True assert m["settings"][0]["default"] == "furtka" def test_reconcile_dry_run_empty(tmp_path, monkeypatch, capsys): _set_env(monkeypatch, tmp_path) rc = main(["reconcile", "--dry-run"]) assert rc == 0 out = capsys.readouterr().out assert "0 actions" in out