import json import pytest from furtka.manifest import Manifest, ManifestError, load_manifest VALID_MANIFEST = { "name": "fileshare", "display_name": "Network Files", "version": "0.1.0", "description": "SMB share", "volumes": ["files"], "ports": [445], "icon": "icon.svg", } def _write_app(tmp_path, name, payload): app_dir = tmp_path / name app_dir.mkdir() (app_dir / "manifest.json").write_text(json.dumps(payload)) return app_dir / "manifest.json" def test_load_valid_manifest(tmp_path): path = _write_app(tmp_path, "fileshare", VALID_MANIFEST) m = load_manifest(path) assert isinstance(m, Manifest) assert m.name == "fileshare" assert m.volumes == ("files",) assert m.ports == (445,) def test_volume_namespacing(tmp_path): path = _write_app(tmp_path, "fileshare", VALID_MANIFEST) m = load_manifest(path) assert m.volume_name("files") == "furtka_fileshare_files" def test_unknown_volume_raises(tmp_path): path = _write_app(tmp_path, "fileshare", VALID_MANIFEST) m = load_manifest(path) with pytest.raises(ManifestError): m.volume_name("does-not-exist") def test_missing_required_field(tmp_path): bad = dict(VALID_MANIFEST) del bad["display_name"] path = _write_app(tmp_path, "fileshare", bad) with pytest.raises(ManifestError, match="display_name"): load_manifest(path) def test_name_must_match_when_expected_name_given(tmp_path): # Scanner passes expected_name= so /var/lib/furtka/apps/X/ # can't lie about its own identity. path = _write_app(tmp_path, "wrong-folder", VALID_MANIFEST) with pytest.raises(ManifestError, match="must equal 'wrong-folder'"): load_manifest(path, expected_name="wrong-folder") def test_name_check_skipped_without_expected_name(tmp_path): # Installer loads from arbitrary source paths (e.g. /tmp/my-tweaked-app/) # — the source folder name shouldn't matter, only the manifest's own name. path = _write_app(tmp_path, "any-folder-name", VALID_MANIFEST) m = load_manifest(path) assert m.name == "fileshare" def test_invalid_json(tmp_path): app = tmp_path / "fileshare" app.mkdir() (app / "manifest.json").write_text("{not json") with pytest.raises(ManifestError, match="invalid JSON"): load_manifest(app / "manifest.json") def test_volumes_wrong_type(tmp_path): bad = dict(VALID_MANIFEST, volumes="files") path = _write_app(tmp_path, "fileshare", bad) with pytest.raises(ManifestError, match="volumes"): load_manifest(path) def test_ports_wrong_type(tmp_path): bad = dict(VALID_MANIFEST, ports=["445"]) path = _write_app(tmp_path, "fileshare", bad) with pytest.raises(ManifestError, match="ports"): load_manifest(path)