83 lines
2.7 KiB
Python
83 lines
2.7 KiB
Python
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
import sys
|
|
import unittest
|
|
from unittest import mock
|
|
|
|
|
|
META_ROOT = Path(__file__).resolve().parents[1]
|
|
RELEASE_TOOLS_ROOT = META_ROOT / "tools" / "release"
|
|
if str(RELEASE_TOOLS_ROOT) not in sys.path:
|
|
sys.path.insert(0, str(RELEASE_TOOLS_ROOT))
|
|
|
|
from govoplan_release.module_directory import ( # noqa: E402
|
|
module_directory_payloads,
|
|
safe_path_part,
|
|
)
|
|
|
|
|
|
class ReleaseModuleDirectoryTests(unittest.TestCase):
|
|
def test_signed_catalog_timestamp_makes_derived_files_reproducible(self) -> None:
|
|
catalog = {
|
|
"generated_at": "2026-07-22T12:00:00Z",
|
|
"sequence": 7,
|
|
"modules": [],
|
|
}
|
|
first = module_directory_payloads(
|
|
catalog_payload=catalog,
|
|
keyring_payload={},
|
|
channel="stable",
|
|
)
|
|
second = module_directory_payloads(
|
|
catalog_payload=catalog,
|
|
keyring_payload={},
|
|
channel="stable",
|
|
)
|
|
|
|
self.assertEqual(first, second)
|
|
self.assertEqual(
|
|
"2026-07-22T12:00:00Z",
|
|
first[-1][1]["generated_at"],
|
|
)
|
|
|
|
def test_dot_segments_and_noncanonical_ids_never_become_paths(self) -> None:
|
|
for value in (".", "..", "../escape", "/absolute", "module/child"):
|
|
with self.subTest(value=value), self.assertRaises(ValueError):
|
|
safe_path_part(value)
|
|
|
|
for module_id in ("..", "../escape", "UPPER", "bad.id"):
|
|
with self.subTest(module_id=module_id), mock.patch(
|
|
"govoplan_release.module_directory.module_rows",
|
|
return_value=[
|
|
{
|
|
"module_id": module_id,
|
|
"version": "1.2.3",
|
|
}
|
|
],
|
|
):
|
|
with self.assertRaises(ValueError):
|
|
module_directory_payloads(
|
|
catalog_payload={},
|
|
keyring_payload={},
|
|
channel="stable",
|
|
)
|
|
|
|
def test_noncanonical_version_and_channel_fail_before_paths(self) -> None:
|
|
with mock.patch(
|
|
"govoplan_release.module_directory.module_rows",
|
|
return_value=[{"module_id": "demo", "version": "../1.2.3"}],
|
|
):
|
|
with self.assertRaises(ValueError):
|
|
module_directory_payloads(
|
|
catalog_payload={}, keyring_payload={}, channel="stable"
|
|
)
|
|
with self.assertRaises(ValueError):
|
|
module_directory_payloads(
|
|
catalog_payload={}, keyring_payload={}, channel="../stable"
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|