from pathlib import Path import copy import importlib.util import json import unittest root = Path(__file__).resolve().parents[1] spec = importlib.util.spec_from_file_location('metered_requester', root / 'scripts/create-metered-approval-requests.py') m = importlib.util.module_from_spec(spec) spec.loader.exec_module(m) class MeteredRequesterTests(unittest.TestCase): def setUp(self): self.rows = json.loads(m.PACKET.read_text()) def test_exact_packet_preserves_separate_human_controls(self): records = m.requests() self.assertEqual(len(records), 6) self.assertEqual(sum(row[1]['human_control'] for row in records), 3) self.assertEqual(len({row[1]['approval_id'] for row in records}), 6) def test_missing_duplicate_or_extra_requests_are_refused(self): for rows in (self.rows[:-1], self.rows + self.rows[:1], self.rows[:-1] + self.rows[:1]): with self.subTest(count=len(rows)), self.assertRaises(ValueError): m.prepare(rows) def test_changed_actor_native_pins_or_human_control_are_refused(self): for change in ('actor', 'native', 'human', 'context'): rows = copy.deepcopy(self.rows) if change == 'actor': rows[0]['request']['subject']['id'] = 'other-service' if change == 'native': rows[0]['decision']['provenance']['policy_package_digest'] = 'sha256:wrong' if change == 'human': rows[0]['request']['context']['human_control'] = False if change == 'context': rows[0]['decision']['binding']['context']['purpose'] = 'different action' with self.subTest(change=change), self.assertRaises(ValueError): m.prepare(rows) def test_frozen_packet_change_refused_before_credential_access(self): from unittest.mock import patch with patch.object(m, 'PACKET_SHA256', '0' * 64), self.assertRaises(ValueError): m.requests() if __name__ == '__main__': unittest.main()