"""Pytest port of the original test_core.py script (same 23 behaviours, now proper test functions with tmp_path/monkeypatch fixtures).""" import json import pytest import bcc_core as c # --------------------------------------------------------------------------- # # 1. Discovery # --------------------------------------------------------------------------- # @pytest.fixture def fake_base(tmp_path, monkeypatch): base = tmp_path / "AppSupport" for d in ("Claude", "Claude-Work", "NotClaude"): (base / d).mkdir(parents=True) (base / "Claude" / c.CONFIG_FILENAME).write_text("{}") monkeypatch.setattr(c, "app_support_base", lambda: base) return base def test_discovers_claude_dirs_not_others(fake_base): labels = sorted(p.label for p in c.discover_profiles()) assert "Claude" in labels assert "Claude-Work" in labels assert "NotClaude" not in labels def test_flags_missing_config_file(fake_base): profs = c.discover_profiles() assert any(p.label == "Claude-Work" and not p.config_exists for p in profs) @pytest.fixture def fake_home(tmp_path, monkeypatch, fake_base): home = tmp_path / "home" (home / ".claude").mkdir(parents=True) monkeypatch.setattr(c.Path, "home", lambda: home) return home def test_claude_code_uses_dot_claude_json(fake_home): (fake_home / ".claude.json").write_text('{"mcpServers": {"x": {"command": "npx"}}}') profs = c.discover_profiles() cc = [p for p in profs if p.label == "Claude Code"] assert len(cc) == 1 assert cc[0].path == fake_home / ".claude.json" assert cc[0].config_exists def test_legacy_settings_json_surfaced_only_with_servers(fake_home): # settings.json without mcpServers -> not listed (fake_home / ".claude" / "settings.json").write_text('{"permissions": {}}') assert not any("legacy" in p.label for p in c.discover_profiles()) # settings.json WITH parked mcpServers -> listed so the user can migrate (fake_home / ".claude" / "settings.json").write_text( '{"mcpServers": {"old": {"command": "npx"}}}' ) assert any("legacy" in p.label for p in c.discover_profiles()) # --------------------------------------------------------------------------- # # 2. Write pipeline: preserves other keys + order, only touches mcpServers # --------------------------------------------------------------------------- # @pytest.fixture def written_config(tmp_path): cfgpath = tmp_path / "real.json" original = { "globalShortcut": "Cmd+Shift+Space", "mcpServers": {"old": {"command": "node", "args": ["x.js"]}}, "someOtherTool": {"keep": True}, } cfgpath.write_text(json.dumps(original, indent=2)) cfg = c.load_config(cfgpath) servers = c.extract_servers(cfg) servers.append(c.ServerEntry("brave", {"command": "npx", "args": ["-y", "@x/brave"]}, True)) servers[0].enabled = False c.apply_servers(cfg, servers) c.write_config(cfgpath, cfg) return cfgpath, json.loads(cfgpath.read_text()) def test_preserves_unrelated_keys(written_config): _, written = written_config assert written.get("globalShortcut") == "Cmd+Shift+Space" assert written.get("someOtherTool") == {"keep": True} def test_disabled_server_parked(written_config): _, written = written_config assert "old" in written.get(c.DISABLED_KEY, {}) assert "old" not in written.get("mcpServers", {}) def test_enabled_server_active(written_config): _, written = written_config assert "brave" in written.get("mcpServers", {}) def test_key_order_kept(written_config): _, written = written_config keys = list(written.keys()) assert keys.index("globalShortcut") < keys.index("mcpServers") def test_backup_created(written_config): cfgpath, _ = written_config bdir = cfgpath.parent / c.BACKUP_DIRNAME assert bdir.is_dir() assert any(bdir.iterdir()) # --------------------------------------------------------------------------- # # 3. Paste parser — all accepted shapes # --------------------------------------------------------------------------- # def test_parse_full_config_shape(): full = '{"mcpServers": {"a": {"command": "node", "args": ["a.js"]}}}' assert list(c.parse_pasted_json(full)) == ["a"] def test_parse_inner_block_shape(): inner = '{"b": {"command": "uvx", "args": ["mcp-server-git"]}}' assert list(c.parse_pasted_json(inner)) == ["b"] def test_parse_bare_server_suggests_name(): bare = '{"command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]}' assert "filesystem" in c.parse_pasted_json(bare) def test_parse_remote_suggests_host_name(): remote = '{"url": "https://mcp.asana.com/sse"}' assert "mcp" in c.parse_pasted_json(remote) def test_rejects_junk(): with pytest.raises(ValueError): c.parse_pasted_json('{"junk": 5}') # --------------------------------------------------------------------------- # # 4. Validation # --------------------------------------------------------------------------- # @pytest.fixture def problems(): bad = [ c.ServerEntry("", {"command": "x"}, True), c.ServerEntry("dup", {"command": "x"}, True), c.ServerEntry("dup", {"command": "x"}, True), c.ServerEntry("r", {"url": ""}, True), c.ServerEntry("nocmd", {"command": ""}, True), ] return c.validate_servers(bad) def test_validation_catches_empty_name(problems): assert any("empty name" in p for p in problems) def test_validation_catches_duplicate(problems): assert any("Duplicate" in p for p in problems) def test_validation_catches_missing_url(problems): assert any("no URL" in p for p in problems) def test_validation_catches_missing_command(problems): assert any("no command" in p for p in problems) def test_valid_set_passes_clean(): assert c.validate_servers([c.ServerEntry("good", {"command": "node"}, True)]) == [] # --------------------------------------------------------------------------- # # 5. Dependency / PATH checking # --------------------------------------------------------------------------- # def test_dep_check_finds_python3(): assert c.check_dependency({"command": "python3"})["status"] == "ok" def test_dep_check_flags_missing(): assert c.check_dependency({"command": "definitely-not-real-binary-xyz"})["status"] == "missing" def test_dep_check_marks_remote(): assert c.check_dependency({"url": "https://example.com/mcp"})["status"] == "remote" def test_dep_check_sees_through_shell_wrapper(): r = c.check_dependency({"command": "cmd", "args": ["/c", "definitely-not-real-xyz", "foo"]}) assert "definitely-not-real-xyz" in r["label"]