"""Tests build SCORM zips in-memory and validate them."""
from __future__ import annotations
import io
import zipfile
from pathlib import Path
from scorm_qa.checks import validate_package
from scorm_qa.manifest import parse_manifest
def _write_zip(path: Path, files: dict[str, str]) -> None:
with zipfile.ZipFile(path, "w") as zf:
for name, contents in files.items():
zf.writestr(name, contents)
GOOD_MANIFEST = """
1.2
Course
- Lesson
"""
def test_good_package_passes(tmp_path):
pkg = tmp_path / "good.zip"
_write_zip(pkg, {
"imsmanifest.xml": GOOD_MANIFEST,
"lesson.html": "Hi",
})
defects, manifest = validate_package(str(pkg))
assert defects == []
assert manifest is not None
assert manifest.schemaversion == "1.2"
def test_missing_manifest_is_critical(tmp_path):
pkg = tmp_path / "no_manifest.zip"
_write_zip(pkg, {"lesson.html": "
"})
defects, manifest = validate_package(str(pkg))
assert manifest is None
assert any(d["severity"] == "CRITICAL" and "imsmanifest" in d["message"] for d in defects)
def test_malformed_xml_is_critical(tmp_path):
pkg = tmp_path / "bad_xml.zip"
_write_zip(pkg, {"imsmanifest.xml": ""})
defects, manifest = validate_package(str(pkg))
assert manifest is None
assert any(d["severity"] == "CRITICAL" and "malformed" in d["message"].lower() for d in defects)
def test_unsupported_schema_version(tmp_path):
bad = GOOD_MANIFEST.replace("1.2",
"9.9")
pkg = tmp_path / "badver.zip"
_write_zip(pkg, {"imsmanifest.xml": bad, "lesson.html": ""})
defects, _ = validate_package(str(pkg))
assert any("9.9" in d["message"] for d in defects)
def test_missing_referenced_file(tmp_path):
pkg = tmp_path / "missing_file.zip"
_write_zip(pkg, {"imsmanifest.xml": GOOD_MANIFEST}) # lesson.html absent
defects, _ = validate_package(str(pkg))
assert any("lesson.html" in d["location"] and d["severity"] == "HIGH" for d in defects)
def test_dangling_file_flagged_low(tmp_path):
pkg = tmp_path / "dangling.zip"
_write_zip(pkg, {
"imsmanifest.xml": GOOD_MANIFEST,
"lesson.html": "",
"extras/notes.txt": "junk",
})
defects, _ = validate_package(str(pkg))
assert any("extras/notes.txt" in d["location"] and d["severity"] == "LOW" for d in defects)