import importlib.util import json import zipfile from pathlib import Path def _load_packager(): path = Path(__file__).resolve().parents[1] / "scripts" / "package_extension.py" spec = importlib.util.spec_from_file_location("package_extension", path) module = importlib.util.module_from_spec(spec) assert spec.loader is not None spec.loader.exec_module(module) return module def _fake_extension(tmp_path: Path) -> Path: extension = tmp_path / "extension" icons = extension / "icons" icons.mkdir(parents=True) (extension / "manifest.json").write_text(json.dumps({ "manifest_version": 3, "name": "browser-cli", "version": "1.2.3", "permissions": ["tabs", "tabGroups", "windows", "nativeMessaging"], "background": {"service_worker": "background.js"}, "browser_specific_settings": {"gecko": {"id": "browser-cli@yiprawr.dev"}}, "key": "test-key", }), encoding="utf-8") for name in ("background.js", "content-dispatch.js", "content.js"): (extension / name).write_text("// generated test bundle\n", encoding="utf-8") (extension / "icon.svg").write_text("\n", encoding="utf-8") (icons / "icon-128.png").write_bytes(b"png") return extension def _packager_with_fake_extension(tmp_path: Path): packager = _load_packager() packager.EXTENSION_DIR = _fake_extension(tmp_path) packager.DIST_DIR = tmp_path / "dist" return packager def test_webstore_package_strips_manifest_key(tmp_path): packager = _packager_with_fake_extension(tmp_path) out = packager.package_extension(webstore=True, out=tmp_path / "webstore.zip") with zipfile.ZipFile(out) as zf: manifest = json.loads(zf.read("manifest.json")) names = set(zf.namelist()) assert "key" not in manifest assert "background.js" in names assert "content-dispatch.js" in names assert "content.js" in names assert "icons/icon-128.png" in names def test_firefox_package_strips_chromium_key_and_firefox_incompatible_permission(tmp_path): packager = _packager_with_fake_extension(tmp_path) out = packager.package_extension(firefox=True, out=tmp_path / "firefox.zip") with zipfile.ZipFile(out) as zf: manifest = json.loads(zf.read("manifest.json")) assert "key" not in manifest assert manifest["browser_specific_settings"]["gecko"]["id"] == "browser-cli@yiprawr.dev" assert "tabGroups" in manifest["permissions"] assert "windows" not in manifest["permissions"] assert "nativeMessaging" in manifest["permissions"] assert "service_worker" not in manifest["background"] assert manifest["background"]["scripts"] == ["background.js"] assert manifest["browser_specific_settings"]["gecko"]["strict_min_version"] == "140.0" assert manifest["browser_specific_settings"]["gecko_android"]["strict_min_version"] == "142.0" assert manifest["browser_specific_settings"]["gecko"]["data_collection_permissions"] == {"required": ["none"]} def test_local_package_keeps_manifest_key(tmp_path): packager = _packager_with_fake_extension(tmp_path) out = packager.package_extension(webstore=False, out=tmp_path / "local.zip") with zipfile.ZipFile(out) as zf: manifest = json.loads(zf.read("manifest.json")) assert manifest["key"] == "test-key"