import base64 import importlib.util import json from pathlib import Path import unittest import yaml spec = importlib.util.spec_from_file_location('portal_rollout', Path(__file__).with_name('portal-client-rollout.py')) rollout = importlib.util.module_from_spec(spec) spec.loader.exec_module(rollout) class PortalClientTests(unittest.TestCase): def fixture(self, clients=None): # Synthetic marker values only; no live Secret is loaded by this suite. raw = ('# preserve this comment\nauthelia:\n issuer: https://auth.example.invalid\n' ' clientSecret: synthetic-marker\nclients:\n' + yaml.safe_dump(json.loads(json.dumps(clients or [{'clientId': 'existing', 'clientType': 'public'}])), sort_keys=False) + 'tokenLifetime: 15m\n') return {'data': {'config.yaml': base64.b64encode(raw.encode()).decode(), 'key.pem': 'synthetic-key'}}, raw def test_add_preserves_other_values_and_original_bytes(self): secret, raw = self.fixture() encoded, changed = rollout.replacement(secret) updated = base64.b64decode(encoded).decode() self.assertTrue(changed) self.assertTrue(updated.startswith(raw[:raw.index('tokenLifetime:')])) self.assertTrue(updated.endswith('tokenLifetime: 15m\n')) expected = yaml.safe_load(raw) expected['clients'].append(rollout.portal.CLIENT) self.assertEqual(yaml.safe_load(updated), expected) self.assertEqual(secret['data']['key.pem'], 'synthetic-key') def test_exact_existing_registration_is_noop(self): secret, _ = self.fixture([rollout.portal.CLIENT]) self.assertEqual(rollout.replacement(secret), (secret['data']['config.yaml'], False)) def test_differing_or_duplicate_registration_refused(self): for clients in [[dict(rollout.portal.CLIENT, redirectUris=['https://other.invalid/callback'])], [rollout.portal.CLIENT, rollout.portal.CLIENT]]: with self.subTest(clients=len(clients)), self.assertRaises(rollout.Refused): rollout.replacement(self.fixture(clients)[0]) def test_bootstrap_retains_same_public_registration(self): source = Path(__file__).with_name('create-secrets.sh').read_text() raw = source.split('CONFIG_YAML=$(cat <