Files
DeDRM_tools/tests/dedrm_test_utils.py
T
JMR-devandClaude Opus 4.8 d407298be4 Update tests for shared helpers and fix test nits
- Cover the new utilities helpers (unpad, crc32, checksumPid type
  preservation, pidFromSerial, safe_join) and drop the now-redundant
  per-module crc32 tests.
- Rename test_unpad_removes_pkcs7_padding to reflect that unpad only
  trusts the trailing pad-length byte rather than validating PKCS#7.
- Replace the KOBO_HASH_KEYS change-detector with a test that documents
  the intentional value pin and checks the ASCII-salt contract.
- Note kgenpids' hybrid import in the test-loader docstring.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 09:18:01 -05:00

64 lines
2.2 KiB
Python

"""Test helpers for importing the calibre plugin modules outside of calibre.
The DeDRM and Obok plugins normally run inside calibre's bundled Python and use
intra-package (``from .x import y``) imports. To unit-test the pure logic we:
* put the plugin source directories on ``sys.path`` (for absolute imports such
as ``import kgenpids`` / ``import alfcrypto``);
* provide a minimal ``calibre`` stub for the few modules that import it;
* register a synthetic ``dedrm`` package whose ``__path__`` points at the
DeDRM_plugin directory, so modules that use relative imports resolve without
executing the real (calibre-dependent) ``__init__.py``.
Modules with no relative imports (alfcrypto, argv_utils, obok) are loaded
top-level; modules with ``from .`` imports are loaded as ``dedrm.X``. kgenpids
is a hybrid: it is imported absolutely by other worker modules, so it falls back
to an absolute ``from utilities import ...`` and is still loaded top-level here.
"""
import importlib
import os
import sys
import types
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DEDRM = os.path.join(ROOT, "DeDRM_plugin")
OBOK = os.path.join(ROOT, "Obok_plugin", "obok")
def _ensure_on_path(path):
if path not in sys.path:
sys.path.insert(0, path)
def _setup():
_ensure_on_path(DEDRM)
_ensure_on_path(OBOK)
# Minimal calibre stub (only the bits the plugin modules touch at import).
if "calibre" not in sys.modules:
sys.modules["calibre"] = types.ModuleType("calibre")
constants = types.ModuleType("calibre.constants")
constants.iswindows = sys.platform.startswith("win")
sys.modules["calibre.constants"] = constants
# Synthetic package so `from .x import y` works without the real __init__.py.
if "dedrm" not in sys.modules:
pkg = types.ModuleType("dedrm")
pkg.__path__ = [DEDRM]
pkg.__package__ = "dedrm"
sys.modules["dedrm"] = pkg
_setup()
def load(module_name, package=None):
"""Import and return a plugin module.
Pass ``package="dedrm"`` for modules that use relative imports.
"""
if package:
return importlib.import_module("{0}.{1}".format(package, module_name))
return importlib.import_module(module_name)