using Bpmn.Interchange; using Bpmn.Model; using Bpmn.Semantics; using Elsa.Bpmn.Interchange.Services; namespace Elsa.Bpmn.Interchange.UnitTests; /// /// Capability refusal at import: is the /// internal seam the Import endpoint calls into, exercised here directly because the current library version defines /// no capability does not already cover, so a /// document genuinely refused by import cannot be produced through the public API today. /// public class BpmnInterchangeDocumentServiceCapabilityTests { [Fact(DisplayName = "A definition needing a capability the host does not declare is refused, naming the capability and the driving element")] public void EnsureCapabilitiesSatisfied_RefusesADefinitionNeedingAnUndeclaredCapability() { var definition = MultiInstanceDefinition("main", "each"); var exception = Assert.Throws(() => BpmnInterchangeDocumentService.EnsureCapabilitiesSatisfied(definition, [], BpmnHostCapabilities.None)); Assert.Equal(BpmnHostCapabilities.IterationScopes, exception.Missing); Assert.Contains("each", exception.DrivingElementIds); } [Fact(DisplayName = "The same definition is accepted once the host declares the capability it needs")] public void EnsureCapabilitiesSatisfied_AcceptsADefinitionOnceTheCapabilityIsDeclared() { var definition = MultiInstanceDefinition("main", "each"); // No exception is the assertion: the capability the definition needs is now declared. BpmnInterchangeDocumentService.EnsureCapabilitiesSatisfied(definition, [], BpmnHostCapabilities.IterationScopes); } [Fact(DisplayName = "A nested process needing an undeclared capability is refused even though the root process needs nothing")] public void EnsureCapabilitiesSatisfied_WalksIntoNestedProcesses() { var nestedDefinition = MultiInstanceDefinition("sub", "each"); var rootDefinition = new BpmnProcessDefinition("main"); BpmnWorkBinding[] bindings = [new BpmnWorkBinding.NestedProcess("main", "sub", "node-sub", BpmnBindingSlot.Primary, nestedDefinition)]; var exception = Assert.Throws(() => BpmnInterchangeDocumentService.EnsureCapabilitiesSatisfied(rootDefinition, bindings, BpmnHostCapabilities.None)); Assert.Equal(BpmnHostCapabilities.IterationScopes, exception.Missing); Assert.Contains("each", exception.DrivingElementIds); } private static BpmnProcessDefinition MultiInstanceDefinition(string processId, string elementId) { var element = new BpmnElement( elementId, BpmnElementTypes.ServiceTask, bindingRef: $"node-{elementId}", loopCharacteristics: new BpmnLoopCharacteristics(isSequential: false, cardinality: 3)); return new BpmnProcessDefinition(processId, Elements: [element]); } }