← Files Arabic DOCX RTLARCHIVED FILE
tests/test_publication.py
16.8 KB · Oct 4, 2026 · 12:32 UTC
from __future__ import annotations
import importlib.util
import json
import tempfile
import unittest
import zipfile
from pathlib import Path
REPOSITORY_ROOT = Path(__file__).resolve().parents[1]
CHECKER_PATH = REPOSITORY_ROOT / "scripts" / "check_publication.py"
REQUIRED_PATHS = (
".codex-plugin/plugin.json",
".gitattributes",
".github/CODEOWNERS",
".github/ISSUE_TEMPLATE/config.yml",
".github/ISSUE_TEMPLATE/image-object.yml",
".github/ISSUE_TEMPLATE/improvement.yml",
".github/ISSUE_TEMPLATE/performance.yml",
".github/ISSUE_TEMPLATE/rtl-rendering.yml",
".github/ISSUE_TEMPLATE/table-layout.yml",
".github/pull_request_template.md",
".github/workflows/quality.yml",
".gitignore",
"CHANGELOG.md",
"CODE_OF_CONDUCT.md",
"CONTRIBUTING.md",
"GOVERNANCE.md",
"LICENSE",
"NOTICE",
"README.ar.md",
"README.md",
"ROADMAP.md",
"SECURITY.md",
"SUPPORT.md",
"assets/BRANDING.md",
"docs/adding-a-guardrail.md",
"docs/architecture-decisions.md",
"docs/compatibility-matrix.md",
"docs/how-it-was-built.md",
"docs/index.md",
"docs/plugin-directory-submission.md",
"docs/privacy-policy.md",
"docs/privacy-and-test-data.md",
"docs/release-process.md",
"docs/terms-of-service.md",
"pyproject.toml",
"release-evidence/plugin-directory-candidate.json",
"release-evidence/plugin-directory-fresh-task-smoke.json",
"release-evidence/plugin-directory-publication.json",
"scripts/check_publication.py",
"scripts/check_plugin_submission.py",
"scripts/build_local_marketplace.py",
"scripts/build_submission_bundle.py",
"submission/availability.md",
"submission/listing.ar.md",
"submission/listing.en.md",
"submission/release-notes.md",
"submission/reviewer-tests.json",
"tests/test_plugin_assets.py",
"tests/test_plugin_submission.py",
"tests/test_local_marketplace.py",
"tests/test_submission_bundle.py",
"skills/arabic-word-production/SKILL.md",
"skills/arabic-word-production/agents/openai.yaml",
"tests/test_publication.py",
)
def load_checker():
if not CHECKER_PATH.is_file():
raise AssertionError(f"publication checker is missing: {CHECKER_PATH}")
spec = importlib.util.spec_from_file_location("publication_checker", CHECKER_PATH)
if spec is None or spec.loader is None:
raise AssertionError("could not load publication checker")
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
def write_docx(path: Path, creator: str = "python-docx", last_modified_by: str = "") -> None:
path.parent.mkdir(parents=True, exist_ok=True)
core_xml = f"""<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cp:coreProperties
xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:creator>{creator}</dc:creator>
<cp:lastModifiedBy>{last_modified_by}</cp:lastModifiedBy>
</cp:coreProperties>"""
with zipfile.ZipFile(path, "w") as package:
package.writestr("docProps/core.xml", core_xml)
class PublicationCheckerTests(unittest.TestCase):
def setUp(self) -> None:
self.temp_dir = tempfile.TemporaryDirectory()
self.addCleanup(self.temp_dir.cleanup)
self.root = Path(self.temp_dir.name)
for relative in REQUIRED_PATHS:
path = self.root / relative
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("safe synthetic content\n", encoding="utf-8")
(self.root / ".codex-plugin/plugin.json").write_text(
json.dumps(
{
"name": "arabic-word-production",
"version": "0.1.1",
"description": "Safe synthetic plugin",
"author": {
"name": "Bannovich",
"email": "73133823+Bannovich@users.noreply.github.com",
},
"license": "Apache-2.0",
"skills": "./skills/",
"interface": {
"displayName": "Arabic Word Production",
"shortDescription": "Synthetic validation fixture",
},
}
),
encoding="utf-8",
)
(self.root / "release-evidence/plugin-directory-fresh-task-smoke.json").write_text(
json.dumps(
{
"schema_version": 1,
"candidate": {
"validated_parent_commit": "0" * 40,
"evidence_commit": "1" * 40,
"package_version": "0.1.0",
"submission_type": "skills-only",
"license": "Apache-2.0",
"plugin_id": "arabic-word-production@arabic-word-production-local",
"qualified_skill_name": "arabic-word-production:arabic-word-production",
},
"fresh_task": {
"passed": True,
"clean_room": True,
"route": "COMPLEX",
"synthetic_only": True,
"source_repository_worktree_used": False,
"plugin_runtime_matches_installed_copy": True,
"installed_plugin_files": 77,
"candidate_bundle_files": 77,
"candidate_bundle_file_mismatches": 0,
},
"timing": {
"task_turn_seconds": 100.0,
"pipeline_model_preparation_through_final_audit_seconds": 1.0,
"build_seconds": 0.5,
"under_120_second_target": {
"task_turn": True,
"pipeline_only": True,
"user_visible_claim": "met",
},
},
"verification": {
"structural_finding_count": 0,
"reopen_finding_count": 0,
"supplemental_checks_passed": 13,
"supplemental_checks_total": 13,
"reopen_supplemental_checks_passed": 13,
"reopen_supplemental_checks_total": 13,
"metrics_identical_after_reopen": True,
"accessibility_findings": {"high": 0, "medium": 0, "low": 0},
},
"artifact_integrity": {
"candidate_plugin_bundle_sha256": "2" * 64,
"generated_docx_sha256": "3" * 64,
"synthetic_model_sha256": "4" * 64,
"independent_reopen_docx_sha256": "5" * 64,
"independent_reopen_byte_identical": False,
"independent_reopen_structurally_equivalent": True,
},
"validation_surface": {
"renderer_attempted": True,
"renderer_available": False,
"rendered_pages": 0,
"inspected_pages": 0,
"word_desktop_tested": False,
"claim": "structural-and-accessibility-only",
},
"openai_portal_state": {
"developer_identity_action_attempted": False,
"policy_attestations_attempted": False,
"submit_for_review_attempted": False,
"publish_attempted": False,
},
}
),
encoding="utf-8",
)
def scan(self):
return load_checker().scan_repository(self.root)
def assert_category(self, result, category: str) -> None:
self.assertFalse(result["ok"])
self.assertIn(category, {item["category"] for item in result["findings"]})
def test_minimal_clean_repository_passes(self) -> None:
result = self.scan()
self.assertTrue(result["ok"], result["findings"])
self.assertEqual([], result["findings"])
def test_current_manifest_matches_release_metadata(self) -> None:
result = load_checker().scan_repository(REPOSITORY_ROOT)
categories = {item["category"] for item in result["findings"]}
self.assertNotIn("plugin-manifest-mismatch", categories, result["findings"])
def test_missing_required_file_is_reported(self) -> None:
(self.root / "NOTICE").unlink()
self.assert_category(self.scan(), "required-path-missing")
def test_missing_branding_source_of_truth_is_reported(self) -> None:
(self.root / "assets/BRANDING.md").unlink()
result = self.scan()
self.assert_category(result, "required-path-missing")
self.assertIn(
"assets/BRANDING.md", {item["path"] for item in result["findings"]}
)
def test_fresh_task_evidence_requires_full_turn_timing(self) -> None:
path = self.root / "release-evidence/plugin-directory-fresh-task-smoke.json"
evidence = json.loads(path.read_text(encoding="utf-8"))
del evidence["timing"]["task_turn_seconds"]
path.write_text(json.dumps(evidence), encoding="utf-8")
self.assert_category(self.scan(), "fresh-task-evidence-invalid")
def test_fresh_task_evidence_rejects_pipeline_only_latency_claim(self) -> None:
path = self.root / "release-evidence/plugin-directory-fresh-task-smoke.json"
evidence = json.loads(path.read_text(encoding="utf-8"))
evidence["timing"]["task_turn_seconds"] = 767.617
evidence["timing"]["under_120_second_target"]["task_turn"] = True
path.write_text(json.dumps(evidence), encoding="utf-8")
self.assert_category(self.scan(), "fresh-task-evidence-invalid")
def test_fresh_task_evidence_requires_a_passing_plugin_invocation(self) -> None:
path = self.root / "release-evidence/plugin-directory-fresh-task-smoke.json"
evidence = json.loads(path.read_text(encoding="utf-8"))
evidence["fresh_task"]["passed"] = False
path.write_text(json.dumps(evidence), encoding="utf-8")
self.assert_category(self.scan(), "fresh-task-evidence-invalid")
def test_fresh_task_evidence_cannot_claim_rendered_pages_without_renderer(self) -> None:
path = self.root / "release-evidence/plugin-directory-fresh-task-smoke.json"
evidence = json.loads(path.read_text(encoding="utf-8"))
evidence["validation_surface"]["rendered_pages"] = 1
evidence["validation_surface"]["inspected_pages"] = 1
path.write_text(json.dumps(evidence), encoding="utf-8")
self.assert_category(self.scan(), "fresh-task-evidence-invalid")
def test_fresh_task_evidence_requires_an_honest_user_visible_claim(self) -> None:
path = self.root / "release-evidence/plugin-directory-fresh-task-smoke.json"
evidence = json.loads(path.read_text(encoding="utf-8"))
evidence["timing"]["under_120_second_target"]["user_visible_claim"] = "not-met"
path.write_text(json.dumps(evidence), encoding="utf-8")
self.assert_category(self.scan(), "fresh-task-evidence-invalid")
def test_fresh_task_evidence_rejects_candidate_file_mismatches(self) -> None:
path = self.root / "release-evidence/plugin-directory-fresh-task-smoke.json"
evidence = json.loads(path.read_text(encoding="utf-8"))
evidence["fresh_task"]["candidate_bundle_file_mismatches"] = 1
path.write_text(json.dumps(evidence), encoding="utf-8")
self.assert_category(self.scan(), "fresh-task-evidence-invalid")
def test_fresh_task_evidence_requires_reopen_and_integrity_proof(self) -> None:
path = self.root / "release-evidence/plugin-directory-fresh-task-smoke.json"
evidence = json.loads(path.read_text(encoding="utf-8"))
del evidence["verification"]["reopen_supplemental_checks_passed"]
evidence["artifact_integrity"]["generated_docx_sha256"] = "not-a-digest"
path.write_text(json.dumps(evidence), encoding="utf-8")
self.assert_category(self.scan(), "fresh-task-evidence-invalid")
def test_fresh_task_evidence_cannot_claim_portal_actions(self) -> None:
path = self.root / "release-evidence/plugin-directory-fresh-task-smoke.json"
evidence = json.loads(path.read_text(encoding="utf-8"))
evidence["openai_portal_state"]["submit_for_review_attempted"] = True
path.write_text(json.dumps(evidence), encoding="utf-8")
self.assert_category(self.scan(), "fresh-task-evidence-invalid")
def test_english_private_visibility_scaffold_language_is_reported(self) -> None:
stale_text = "Until the repository " + "is public, use the local folder."
(self.root / "README.md").write_text(stale_text, encoding="utf-8")
self.assert_category(self.scan(), "stale-publication-state")
def test_english_prepublication_plugin_wording_is_reported(self) -> None:
stale_text = "The plugin is not " + "listed or approved there yet."
(self.root / "README.md").write_text(stale_text, encoding="utf-8")
self.assert_category(self.scan(), "stale-publication-state")
def test_arabic_private_visibility_scaffold_language_is_reported(self) -> None:
stale_text = "قبل ما الـRepository يبقى " + "Public، استخدم المجلد المحلي."
(self.root / "README.ar.md").write_text(stale_text, encoding="utf-8")
self.assert_category(self.scan(), "stale-publication-state")
def test_arabic_prepublication_plugin_wording_is_reported(self) -> None:
stale_text = "الـPlugin ليس " + "معتمدًا أو ظاهرًا هناك حتى الآن."
(self.root / "README.ar.md").write_text(stale_text, encoding="utf-8")
self.assert_category(self.scan(), "stale-publication-state")
def test_chat_conversation_reference_is_reported(self) -> None:
scheme = "chatgpt" + "-conversation://"
(self.root / "notes.md").write_text(scheme + "private-reference", encoding="utf-8")
self.assert_category(self.scan(), "conversation-reference")
def test_conversation_identifier_field_is_reported(self) -> None:
field = "conversation" + "Id"
(self.root / "notes.json").write_text(
json.dumps({field: "private-reference"}), encoding="utf-8"
)
self.assert_category(self.scan(), "conversation-identifier")
def test_windows_user_profile_path_is_reported(self) -> None:
private_path = "C:" + "\\Users\\" + "SampleUser\\private.docx"
(self.root / "notes.md").write_text(private_path, encoding="utf-8")
self.assert_category(self.scan(), "user-profile-path")
def test_private_key_marker_is_reported(self) -> None:
marker = "-----BEGIN " + "PRIVATE KEY-----"
(self.root / "notes.txt").write_text(marker, encoding="utf-8")
self.assert_category(self.scan(), "private-key")
def test_token_prefix_is_reported_without_echoing_secret(self) -> None:
token = "gh" + "p_" + "A" * 36
(self.root / "notes.txt").write_text(token, encoding="utf-8")
result = self.scan()
self.assert_category(result, "credential-token")
self.assertNotIn(token, json.dumps(result))
def test_non_noreply_email_is_reported(self) -> None:
email = "person" + "@example.com"
(self.root / "notes.md").write_text(email, encoding="utf-8")
self.assert_category(self.scan(), "email-address")
def test_github_noreply_email_is_allowed(self) -> None:
(self.root / "notes.md").write_text(
"73133823+Bannovich@users.noreply.github.com", encoding="utf-8"
)
self.assertTrue(self.scan()["ok"])
def test_office_core_identity_metadata_is_reported(self) -> None:
creator = "Private Person"
email = "private" + "@example.com"
write_docx(self.root / "fixture.docx", creator=creator, last_modified_by=email)
result = self.scan()
self.assert_category(result, "office-metadata")
serialized = json.dumps(result)
self.assertNotIn(creator, serialized)
self.assertNotIn(email, serialized)
def test_generic_python_docx_metadata_is_allowed(self) -> None:
write_docx(self.root / "fixture.docx")
self.assertTrue(self.scan()["ok"])
def test_pep639_license_expression_does_not_repeat_legacy_classifier(self) -> None:
pyproject = (REPOSITORY_ROOT / "pyproject.toml").read_text(encoding="utf-8")
self.assertIn('license = "Apache-2.0"', pyproject)
self.assertNotIn(
'"License :: OSI Approved :: Apache Software License"',
pyproject,
"Setuptools 77+ rejects a PEP 639 license expression combined with the legacy license classifier",
)
if __name__ == "__main__":
unittest.main()
SHA-256: ae3a4396ce7435b16d665981fcdca668243d73c32f230fb3d9165f627a71ed73