"""Every module must be extensible without editing the kit. These tests pin the extension points that let a pip-installed consumer add storage backends, pipeline steps, an invoice builder, or a 2FA method purely through settings/registries, and confirm the public import surface. """ import io import pytest from django.core.exceptions import ImproperlyConfigured pytestmark = pytest.mark.django_db # --- fakes referenced by dotted path from settings -------------------------- class FakeStorage: def __init__(self, config): self.config = config self.saved = {} def save(self, name, content): self.saved[name] = content.read() return name def open(self, name, mode="rb"): return io.BytesIO(self.saved[name]) def exists(self, name): return name in self.saved def url(self, name): return f"/fake/{name}" def delete(self, name): self.saved.pop(name, None) def generate_signed_url(self, name, expiry_seconds=3600): return f"/fake/{name}?signed=1" class RecordingExecutor: def execute(self, execution): execution.status = "completed" execution.save(update_fields=["status"]) return execution def fake_invoice_builder(invoice): return b"%PDF-1.4 custom-builder" class FakeTwoFactorService: def generate_secret(self): return "FAKESECRET" class TestPublicImportSurface: def test_app_packages_expose_public_names(self): from infrasynth.audit import ModelChangeLog from infrasynth.billing import EntitlementService, Plan from infrasynth.features import FeatureService from infrasynth.files import FileService, get_storage_backend from infrasynth.gates import GatePermission from infrasynth.notifications import NotificationService from infrasynth.scheduler import TaskService from infrasynth.security import AuthorizationService, HybridPermission from infrasynth.shared import Result from infrasynth.tenancy import TenantManager from infrasynth.webhooks import EventRegistry from infrasynth.workflows import WorkflowEngine assert all( x is not None for x in ( ModelChangeLog, EntitlementService, Plan, FeatureService, FileService, get_storage_backend, NotificationService, TaskService, AuthorizationService, HybridPermission, Result, TenantManager, EventRegistry, WorkflowEngine, GatePermission, ) ) def test_unknown_attribute_raises(self): import infrasynth.security as security with pytest.raises(AttributeError): security.ThisDoesNotExist class TestStorageExtension: def test_custom_backend_via_settings_class(self, settings): settings.INFRASYNTH_FILES = { **settings.INFRASYNTH_FILES, "STORAGE_BACKENDS": { **settings.INFRASYNTH_FILES.get("STORAGE_BACKENDS", {}), "fake": {"CLASS": "tests.test_extensibility.FakeStorage", "REGION": "x"}, }, } storage = get_backend("fake") assert isinstance(storage, FakeStorage) assert storage.config.get("REGION") == "x" def test_custom_backend_via_registry(self): from infrasynth.files.storage import register_storage_backend register_storage_backend("factory-made", FakeStorage) assert isinstance(get_backend("factory-made"), FakeStorage) def test_unknown_backend_raises(self): from infrasynth.files.storage import get_storage_backend with pytest.raises(ImproperlyConfigured): get_storage_backend("does-not-exist") class TestPipelineExtension: def test_registered_step_is_used(self, settings, user, media_root): from django.core.files.uploadedfile import SimpleUploadedFile from infrasynth.files.models import PipelineExecution, ProcessingPipeline from infrasynth.files.processing import PipelineExecutor, pipeline_step from infrasynth.files.services import FileService calls = [] @pipeline_step("test.tag") def tag_step(data, mime_type, params): calls.append(params) return data, mime_type uploaded = FileService().upload( SimpleUploadedFile("a.txt", b"hello", content_type="text/plain"), filename="a.txt", user=user, ) pipeline = ProcessingPipeline.objects.create( name="Tag", slug="tag", steps=[{"type": "test.tag", "params": {"k": "v"}}] ) execution = PipelineExecution.objects.create(file=uploaded, pipeline=pipeline) PipelineExecutor().execute(execution) execution.refresh_from_db() assert execution.status == PipelineExecution.Status.COMPLETED assert calls == [{"k": "v"}] def test_executor_is_swappable(self, settings): from infrasynth.files.processing import get_pipeline_executor settings.INFRASYNTH_FILES = { **settings.INFRASYNTH_FILES, "PIPELINE_EXECUTOR": "tests.test_extensibility.RecordingExecutor", } assert isinstance(get_pipeline_executor(), RecordingExecutor) class TestInvoiceBuilderExtension: def test_builder_is_swappable(self, settings): from infrasynth.billing.invoice_generator import get_invoice_pdf_builder settings.INFRASYNTH_BILLING = { **settings.INFRASYNTH_BILLING, "INVOICE_PDF_BUILDER": "tests.test_extensibility.fake_invoice_builder", } assert get_invoice_pdf_builder()(object()) == b"%PDF-1.4 custom-builder" class TestTwoFactorExtension: def test_service_is_swappable(self, settings): from infrasynth.security.two_factor.services import get_two_factor_service settings.INFRASYNTH_SECURITY = { **settings.INFRASYNTH_SECURITY, "TWO_FACTOR_SERVICE": "tests.test_extensibility.FakeTwoFactorService", } assert get_two_factor_service().generate_secret() == "FAKESECRET" def get_backend(name): from infrasynth.files.storage import get_storage_backend return get_storage_backend(name)