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()