railiance-platform/tests/test_sitting_requester_provisioning.py
codex 356d84a095
All checks were successful
CCR intake gate / gate (push) Successful in 3m15s
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Sitting requester: accept approval:create+read; one-shot refuses re-run; CCR-0026/0027 amendment proposed
key-cape 82b471f (founder decision 2026-11-01) adds approval:read to
informed-decision-sitting-requester. provision-sitting-requester.py contract()
now requires exactly [approval:create, approval:read] and still refuses
consume, approve and openid. The one-shot helper refuses to re-run once its
2026-09-15 receipt is applied, before it could overwrite that evidence, and
names keycape-client.py remove-then-add. Tests updated. CCR-2026-0026/0027:
text-only amendment_proposed; custody, policy, role and delivery unchanged,
so no new CCR and status stays applied.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 5502@bnt-lap001
Assistant-Session: 68b3b02f-5d0f-4e71-8421-796f62e50196
2026-11-01 04:04:15 +01:00

74 lines
3.8 KiB
Python

import importlib.util
from pathlib import Path
import unittest
spec = importlib.util.spec_from_file_location(
'sitting', Path(__file__).resolve().parents[1] / 'scripts/provision-sitting-requester.py')
m = importlib.util.module_from_spec(spec)
spec.loader.exec_module(m)
class SittingRequesterProvisioningTests(unittest.TestCase):
def test_contract_is_create_and_read_informed_decision(self):
# key-cape 82b471f, founder decision 2026-11-01: approval:read for present_existing.
m.contract()
self.assertEqual(m.CLIENT['clientId'], 'informed-decision-sitting-requester')
self.assertEqual(m.CLIENT['allowedScopes'], ['approval:create', 'approval:read'])
self.assertEqual(m.CLIENT['serviceSubject'], 'informed-decision')
self.assertEqual(m.CCRS, ('CCR-2026-0026', 'CCR-2026-0027'))
self.assertNotIn('CCR-2026-0024', m.CCRS)
self.assertNotIn('CCR-2026-0025', m.CCRS)
def test_contract_refuses_widened_or_narrowed_scopes(self):
original = list(m.CLIENT['allowedScopes'])
try:
for scopes in (['approval:create', 'approval:read', 'approval:consume'],
['approval:create', 'approval:read', 'approval:approve'],
['approval:create', 'approval:read', 'openid'],
['approval:create', 'approval:consume'],
['approval:create'],
['approval:read', 'approval:create']):
m.CLIENT['allowedScopes'] = scopes
with self.assertRaises(Exception, msg=scopes):
m.contract()
finally:
m.CLIENT['allowedScopes'] = original
def test_one_shot_refuses_rerun_and_names_remove_then_add(self):
self.assertTrue(m.already_provisioned())
self.assertIn('keycape-client.py', m.RERUN_REFUSAL)
self.assertIn('remove-then-add', m.RERUN_REFUSAL)
source = Path(m.__file__).read_text()
main = source.split("if __name__ == '__main__':", 1)[1]
self.assertLess(main.index('already_provisioned()'), main.index('RECEIPT.write_text'))
def test_source_keycape_registration_matches_helper(self):
import yaml
clients = yaml.safe_load(Path('/home/worsch/key-cape/config/service-clients.example.yaml').read_text())['clients']
named = next(c for c in clients if c['clientId'] == 'informed-decision-sitting-requester')
self.assertEqual(named['secretRef'], 'env:' + m.ENV_NAME)
self.assertEqual(named['allowedScopes'], ['approval:create', 'approval:read'])
for forbidden in ('approval:consume', 'approval:approve', 'openid'):
self.assertNotIn(forbidden, named['allowedScopes'])
self.assertEqual(named['serviceSubject'], 'informed-decision')
class SittingRequesterExchangeTests(unittest.TestCase):
def test_exchange_helper_does_not_post_sittings(self):
spec = importlib.util.spec_from_file_location(
'exchange', Path(__file__).resolve().parents[1] / 'scripts/prove-sitting-requester-exchange.py')
exchange = importlib.util.module_from_spec(spec)
spec.loader.exec_module(exchange)
source = Path(exchange.__file__).read_text()
self.assertNotIn('/v1/approvals', source)
self.assertEqual(exchange.CLIENT_ID, 'informed-decision-sitting-requester')
self.assertEqual(exchange.POLICY, 'workload-kv-read-informed-decision-sitting-requester-client')
self.assertIn('approval-requester', exchange.SIBLING)
self.assertTrue(exchange.is_deny(['deny']))
self.assertTrue(exchange.is_deny([]))
self.assertFalse(exchange.is_deny(['read']))
self.assertEqual(exchange.capabilities({'data': {'capabilities': ['read']}}), ['read'])
if __name__ == '__main__':
unittest.main()