Files
Artemis-Eapil/tests/unit/test_codex_skill_sync.py
chenmingxuan e1ea099592 feat: add official Codex skill and harden task execution
Install and update artemis-use with task diagnostics and plugin guidance. Preserve cross-device file receipts, review canonical reports, guard stage transitions and reduce small history summaries. Improve exploration lifecycle, request recovery and browser live connections.
2026-10-18 14:18:37 +08:00

125 lines
5.3 KiB
Python

import json
from pathlib import Path
from unittest.mock import Mock
import pytest
from artemis.integrations import codex_skill as integration
@pytest.fixture
def bundle(tmp_path, monkeypatch):
root = tmp_path / "source"
source = root / "skills" / "artemis-use"
source.mkdir(parents=True)
(source / "SKILL.md").write_text(
"---\nname: artemis-use\ndescription: official\n---\n", "utf-8"
)
(source / "references").mkdir()
(source / "references" / "modes.md").write_text("official modes", "utf-8")
codex_home = tmp_path / "用户配置" / ".codex"
monkeypatch.setenv("CODEX_HOME", str(codex_home))
return root, source, codex_home
def test_install_overwrites_entire_reserved_directory_and_is_noop_when_unchanged(bundle):
root, source, home = bundle
target = home / "skills" / "artemis-use"
target.mkdir(parents=True)
(target / "SKILL.md").write_text("unmanaged custom content", "utf-8")
(target / "custom.txt").write_text("must be removed", "utf-8")
unrelated = home / "skills" / "personal" / "SKILL.md"
unrelated.parent.mkdir()
unrelated.write_text("personal", "utf-8")
assert integration.sync_official_skill(root)["status"] == "updated"
assert not (target / "custom.txt").exists()
assert (target / "SKILL.md").read_bytes() == (source / "SKILL.md").read_bytes()
assert unrelated.read_text("utf-8") == "personal"
before = (target / "SKILL.md").stat().st_mtime_ns
assert integration.sync_official_skill(root)["status"] == "unchanged"
assert (target / "SKILL.md").stat().st_mtime_ns == before
(target / "SKILL.md").write_text("edited", "utf-8")
assert integration.sync_official_skill(root)["status"] == "updated"
assert (target / "SKILL.md").read_bytes() == (source / "SKILL.md").read_bytes()
def test_update_removes_retired_files_and_migrates_only_marked_rules(bundle):
root, source, home = bundle
integration.sync_official_skill(root)
original = "user prefix\n<!-- BEGIN ARTEMIS MOBILE TESTING RULES -->\nold\n<!-- END ARTEMIS MOBILE TESTING RULES -->\nuser suffix\n"
for name in ("AGENTS.md", "AGENTS.override.md"):
(home / name).write_text(original, "utf-8")
(source / "references" / "modes.md").unlink()
integration.sync_official_skill(root)
assert not (home / "skills/artemis-use/references/modes.md").exists()
for name in ("AGENTS.md", "AGENTS.override.md"):
assert (home / name).read_text("utf-8") == "user prefix\nuser suffix\n"
assert (home / (name + ".artemis-update.bak")).read_text("utf-8") == original
def test_failed_replacement_restores_previous_bundle(bundle, monkeypatch):
root, source, home = bundle
integration.sync_official_skill(root)
target = home / "skills/artemis-use"
original = (target / "SKILL.md").read_bytes()
(source / "SKILL.md").write_text("new version", "utf-8")
rename = Path.rename
def fail_staging(path, destination):
if path.name.startswith(".artemis-use-stage-"):
raise PermissionError("held open")
return rename(path, destination)
monkeypatch.setattr(Path, "rename", fail_staging)
assert integration.sync_skill_safely(root)["status"] == "error"
assert (target / "SKILL.md").read_bytes() == original
assert not list(target.parent.glob(".artemis-use-stage-*"))
def test_newer_official_bundle_is_not_downgraded(bundle):
root, _, home = bundle
integration.sync_official_skill(root)
stamp = home / "skills/artemis-use" / integration.STAMP
data = json.loads(stamp.read_text("utf-8"))
data["artemis_version"] = "99.0.0"
stamp.write_text(json.dumps(data), "utf-8")
assert integration.sync_official_skill(root)["status"] == "newer_installed"
def test_default_directory_and_duplicate_cleanup(bundle, tmp_path, monkeypatch):
root, source, _ = bundle
monkeypatch.delenv("CODEX_HOME")
monkeypatch.setattr(Path, "home", lambda: tmp_path)
legacy = tmp_path / ".codex/skills/artemis-use"
legacy.mkdir(parents=True)
(legacy / "SKILL.md").write_text("old", "utf-8")
assert integration.sync_official_skill(root)["path"] == str(legacy)
modern = tmp_path / ".agents/skills/artemis-use"
modern.mkdir(parents=True)
(modern / "SKILL.md").write_text("duplicate", "utf-8")
assert integration.sync_official_skill(root)["path"] == str(modern)
assert not legacy.exists()
def test_actual_bundle_links_are_self_contained():
import re
source = Path(__file__).resolve().parents[2] / "skills/artemis-use"
for document in source.rglob("*.md"):
for relative in re.findall(r"\]\(([^)]+)\)", document.read_text("utf-8")):
if "://" in relative or relative.startswith("#"):
continue
target = (document.parent / relative.split("#", 1)[0]).resolve()
assert target.is_relative_to(source.resolve()), (document, relative)
assert target.exists(), (document, relative)
def test_malformed_stamp_does_not_block_authoritative_update(bundle):
root, source, home = bundle
integration.sync_official_skill(root)
target = home / "skills/artemis-use"
(target / integration.STAMP).write_text("[]", "utf-8")
(target / "SKILL.md").write_text("unofficial", "utf-8")
assert integration.sync_official_skill(root)["status"] == "updated"
assert (target / "SKILL.md").read_bytes() == (source / "SKILL.md").read_bytes()