"""Regression for ruff F821 in Worker._tenant_dirs (worker.py:2780). The playwright seeding branch logged ``task.get("project_id")`` even though ``_tenant_dirs`` only receives ``project_id`` -- there is no ``task`` variable in scope. The branch is only reached when playwright seeding is on AND the seeder reports a refreshed script, so ordinary seeding tests (flag off, or no refresh) never hit it: at runtime the log call raised NameError and aborted tenant seeding for an existing project whose playwright scripts had just been refreshed. No Docker, no network: _tenant_dirs runs against temp dirs and the playwright seeder is patched to report a refresh, so the test proves only that the log branch uses the method argument, not that real scripts are copied. """ import os import sys import tempfile import unittest from pathlib import Path from unittest import mock try: from cloud.server import init_db from cloud.worker import Worker except ImportError: sys.path.insert(0, str(Path(__file__).resolve().parents[2])) from cloud.server import init_db from cloud.worker import Worker class WorkerPlaywrightSeedF821TestCase(unittest.TestCase): def setUp(self): self.tmp = tempfile.TemporaryDirectory() self.db_path = os.path.join(self.tmp.name, "control.db") init_db(self.db_path) self.template_home = os.path.join(self.tmp.name, "tpl-home") os.makedirs(self.template_home) open(os.path.join(self.template_home, "config.toml"), "w").write('[model_provider.xcmapi]\n' 'base_url="https://xcmapi.org/v1"\n') self.template_repo = os.path.join(self.tmp.name, "tpl-repo") os.makedirs(os.path.join(self.template_repo, ".git")) open(os.path.join(self.template_repo, "sample.py"), "w").write("def add(a, b):\n return a + b\n") def tearDown(self): self.tmp.cleanup() def _worker(self): return Worker( self.db_path, "/fake/host.py", env={"XCM_API_KEY": "test-placeholder"}, tenants_root=os.path.join(self.tmp.name, "tenants"), tenant_template_home=self.template_home, tenant_template_repo=self.template_repo, tenant_isolation=True, playwright_mcp=True) def test_refreshed_script_logs_project_id_without_name_error(self): # Pre-fix this raised NameError: name 'task' is not defined. worker = self._worker() with mock.patch("cloud.worker._ensure_playwright_mcp", return_value={"script_refreshed": ["playwright_mcp.py"]}): with self.assertLogs(worker.logger, level="INFO") as logs: dirs = worker._tenant_dirs("projA") self.assertIn("codex_home", dirs) self.assertTrue(any("projA" in line and "playwright_mcp.py" in line for line in logs.output)) def test_no_refresh_still_seeds(self): worker = self._worker() with mock.patch("cloud.worker._ensure_playwright_mcp", return_value={"script_refreshed": []}): dirs = worker._tenant_dirs("projA") self.assertIn("codex_home", dirs) if __name__ == "__main__": unittest.main()