# -*- coding: utf-8 -*- """e2e_helpers 轻量单元测试(不依赖匠厂桌面 / IPC)。""" from __future__ import annotations import tempfile import unittest from pathlib import Path from jiangchang_desktop_sdk.e2e_helpers import ( SkillDataDir, _iter_text_and_newlines, _is_placeholder_value, _parse_env_file, assert_skill_env_file, ) def _segments(prompt: str) -> list[str | None]: out: list[str | None] = [] for seg in _iter_text_and_newlines(prompt): if seg is not None and not isinstance(seg, str): out.append(None) else: out.append(seg) # type: ignore[arg-type] return out class TestIterTextAndNewlines(unittest.TestCase): def test_lf(self) -> None: self.assertEqual(_segments("a\nb"), ["a", None, "b"]) def test_crlf(self) -> None: self.assertEqual(_segments("a\r\nb"), ["a", None, "b"]) def test_cr(self) -> None: self.assertEqual(_segments("a\rb"), ["a", None, "b"]) def test_multiple_newlines(self) -> None: self.assertEqual(_segments("x\n\ny"), ["x", None, None, "y"]) class TestParseEnvFile(unittest.TestCase): def _write(self, path: Path, content: str) -> None: path.write_text(content, encoding="utf-8") def test_basic_and_comments(self) -> None: with tempfile.TemporaryDirectory() as tmp: env_path = Path(tmp) / ".env" self._write( env_path, "# comment\n\nAPI_KEY=real-secret\n# KEY=ignored\n", ) parsed = _parse_env_file(env_path) self.assertEqual(parsed["API_KEY"], "real-secret") self.assertNotIn("KEY", parsed) def test_quoted_values(self) -> None: with tempfile.TemporaryDirectory() as tmp: env_path = Path(tmp) / ".env" self._write(env_path, 'A="double"\nB=\'single\'\n') parsed = _parse_env_file(env_path) self.assertEqual(parsed["A"], "double") self.assertEqual(parsed["B"], "single") def test_placeholder_detection(self) -> None: self.assertTrue(_is_placeholder_value("TODO", None)) self.assertTrue(_is_placeholder_value("sk-xxx", None)) self.assertTrue(_is_placeholder_value(" Changeme ", None)) self.assertFalse(_is_placeholder_value("sk-live-abc", None)) class TestAssertSkillEnvFile(unittest.TestCase): def test_missing_file(self) -> None: with tempfile.TemporaryDirectory() as tmp: ctx = SkillDataDir( root=Path(tmp), path=Path(tmp) / "user" / "demo-skill", user_id="12428", skill_slug="demo-skill", ) with self.assertRaises(AssertionError) as cm: assert_skill_env_file(ctx, ["API_KEY"]) self.assertIn("config/.env", str(cm.exception)) def test_missing_and_placeholder_keys(self) -> None: with tempfile.TemporaryDirectory() as tmp: skill_dir = Path(tmp) / "12428" / "demo-skill" env_dir = skill_dir / "config" env_dir.mkdir(parents=True) (env_dir / ".env").write_text( "API_KEY=your-key\nOTHER=real\n", encoding="utf-8", ) ctx = SkillDataDir( root=Path(tmp), path=skill_dir, user_id="12428", skill_slug="demo-skill", ) with self.assertRaises(AssertionError) as cm: assert_skill_env_file(ctx, ["API_KEY", "MISSING", "OTHER"]) msg = str(cm.exception) self.assertIn("API_KEY", msg) self.assertIn("MISSING", msg) self.assertNotIn("OTHER", msg) def test_pass_returns_path(self) -> None: with tempfile.TemporaryDirectory() as tmp: skill_dir = Path(tmp) / "1" / "demo-skill" env_dir = skill_dir / "config" env_dir.mkdir(parents=True) env_file = env_dir / ".env" env_file.write_text("API_KEY=sk-live-ok\n", encoding="utf-8") ctx = SkillDataDir( root=Path(tmp), path=skill_dir, user_id="1", skill_slug="demo-skill", ) got = assert_skill_env_file(ctx, ["API_KEY"]) self.assertEqual(got, env_file) if __name__ == "__main__": unittest.main()