< Summary

Information
Class: Elsa.Workflows.Activities.Flowchart.Extensions.ActivityExecutionContextExtensions
Assembly: Elsa.Workflows.Core
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Extensions/ActivityExecutionContextExtensions.cs
Line coverage
89%
Covered lines: 44
Uncovered lines: 5
Coverable lines: 49
Total lines: 135
Line coverage: 89.7%
Branch coverage
80%
Covered branches: 29
Total branches: 36
Branch coverage: 80.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
GetStartActivity(...)100%1010100%
GetTriggerActivity(...)100%22100%
GetExplicitStartActivity(...)100%11100%
GetCanStartWorkflowActivity(...)100%11100%
HasPendingWork(...)100%66100%
GetFlowGraph(...)100%11100%
CancelInboundAncestorsAsync()75%4485.71%
HasUnconsumedTokens(...)75%44100%
HasRunningActivityInstances(...)100%11100%
HasScheduledWork(...)37.5%9875%
HasFaultedChildren(...)100%11100%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Extensions/ActivityExecutionContextExtensions.cs

#LineLine coverage
 1using Elsa.Extensions;
 2using Elsa.Workflows.Activities.Flowchart.Models;
 3
 4namespace Elsa.Workflows.Activities.Flowchart.Extensions;
 5
 6public static class ActivityExecutionContextExtensions
 7{
 8    private const string GraphTransientProperty = "FlowGraph";
 9
 10    extension(Activities.Flowchart flowchart)
 11    {
 12        public IActivity? GetStartActivity(string? triggerActivityId)
 13        {
 182914            return flowchart.GetTriggerActivity(triggerActivityId)
 182915                   ?? flowchart.Start
 182916                   ?? flowchart.GetExplicitStartActivity()
 182917                   ?? flowchart.GetCanStartWorkflowActivity()
 182918                   ?? flowchart.GetRootActivity()
 182919                   ?? flowchart.Activities.FirstOrDefault();
 20        }
 21
 22        /// <summary>
 23        /// Gets the activity that was triggered by the specified trigger activity ID.
 24        /// </summary>
 25        public IActivity? GetTriggerActivity(string? triggerActivityId)
 26        {
 182927            return triggerActivityId == null
 182928                ? null :
 325229                flowchart.Activities.FirstOrDefault(x => x.Id == triggerActivityId);
 30        }
 31
 32        /// <summary>
 33        /// Gets the explicit Start activity from the flowchart.
 34        /// </summary>
 35        public IActivity? GetExplicitStartActivity()
 36        {
 174337            return flowchart.Activities.FirstOrDefault(x => x is Start);
 38        }
 39
 40        /// <summary>
 41        /// Gets the first activity marked as "Can Start Workflow".
 42        /// </summary>
 43        public IActivity? GetCanStartWorkflowActivity()
 44        {
 173545            return flowchart.Activities.FirstOrDefault(x => x.GetCanStartWorkflow());
 46        }
 47    }
 48
 49    extension(ActivityExecutionContext context)
 50    {
 51        /// <summary>
 52        /// Checks if there is any pending work for the flowchart.
 53        /// </summary>
 54        public bool HasPendingWork()
 55        {
 101356            return context.HasRunningActivityInstances()
 101357                   || context.HasScheduledWork()
 101358                   || context.HasUnconsumedTokens()
 101359                   || context.HasFaultedChildren();
 60        }
 61
 62        public FlowGraph GetFlowGraph()
 63        {
 64            // Store in TransientProperties so FlowChart is not persisted in WorkflowState
 113265            var flowchart = (Activities.Flowchart)context.Activity;
 113266            var startActivity = flowchart.GetStartActivity(context.WorkflowExecutionContext.TriggerActivityId);
 181867            return context.TransientProperties.GetOrAdd(GraphTransientProperty, () => new FlowGraph(flowchart.Connection
 68        }
 69
 70        public async Task CancelInboundAncestorsAsync(IActivity activity)
 71        {
 2272            if(context.Activity is not Activities.Flowchart)
 073                throw new InvalidOperationException("Activity context is not a flowchart.");
 74
 2275            var flowGraph = context.GetFlowGraph();
 2276            var ancestorActivities = flowGraph.GetAncestorActivities(activity);
 17277            var inboundActivityExecutionContexts = context.WorkflowExecutionContext.ActivityExecutionContexts.Where(x =>
 78
 79            // Cancel each ancestor activity.
 23080            foreach (var activityExecutionContext in inboundActivityExecutionContexts)
 81            {
 9382                await activityExecutionContext.CancelActivityAsync();
 83            }
 2284        }
 85
 86        /// <summary>
 87        /// Checks if the flowchart has any unconsumed tokens.
 88        /// </summary>
 89        public bool HasUnconsumedTokens()
 90        {
 68591            var flowchart = (Activities.Flowchart)context.Activity;
 92892            return flowchart.GetTokenList(context).Any(x => x is { Consumed: false, Blocked: false });
 93        }
 94
 95        /// <summary>
 96        /// Checks if the flowchart has any running activity instances.
 97        /// </summary>
 98        public bool HasRunningActivityInstances()
 99        {
 1013100            var flowchart = (Activities.Flowchart)context.Activity;
 3306101            var activityIds = flowchart.Activities.Select(x => x.Id).ToList();
 1013102            var children = context.Children;
 4327103            return children.Where(x => activityIds.Contains(x.Activity.Id)).Any(x => x.Status == ActivityStatus.Running)
 104        }
 105
 106        /// <summary>
 107        /// Checks if the flowchart has any scheduled work items.
 108        /// </summary>
 109        public bool HasScheduledWork()
 110        {
 1013111            var workflowExecutionContext = context.WorkflowExecutionContext;
 112
 1013113            return workflowExecutionContext.Scheduler.List().Any(workItem =>
 1013114            {
 328115                var ownerInstanceId = workItem.Owner?.Id;
 1013116
 328117                if (ownerInstanceId == null)
 0118                    return false;
 1013119
 328120                if (ownerInstanceId == context.Id)
 328121                    return true;
 1013122
 0123                var ownerContext = context.WorkflowExecutionContext.ActivityExecutionContexts.First(x => x.Id == ownerIn
 0124                var ancestors = ownerContext.GetAncestors().ToList();
 1013125
 0126                return ancestors.Any(x => x == context);
 1013127            });
 128        }
 129
 130        public bool HasFaultedChildren()
 131        {
 1784132            return context.Children.Any(x => x.Status == ActivityStatus.Faulted);
 133        }
 134    }
 135}