< Summary

Information
Class: Elsa.Workflows.Management.Mappers.WorkflowDefinitionMapper
Assembly: Elsa.Workflows.Management
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Management/Mappers/WorkflowDefinitionMapper.cs
Line coverage
61%
Covered lines: 80
Uncovered lines: 51
Coverable lines: 131
Total lines: 226
Line coverage: 61%
Branch coverage
70%
Covered branches: 24
Total branches: 34
Branch coverage: 70.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
Map(...)100%22100%
MapFromModelWithIdentity(...)100%1010100%
Map(...)100%1212100%
MapToWorkflowDefinition(...)0%110100%
<MapAsync()100%210%
MapAsync()100%210%
MapAsync()100%11100%
Map(...)100%210%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Management/Mappers/WorkflowDefinitionMapper.cs

#LineLine coverage
 1using Elsa.Workflows.Activities;
 2using Elsa.Workflows.Management.Entities;
 3using Elsa.Workflows.Management.Materializers;
 4using Elsa.Workflows.Management.Models;
 5using Elsa.Workflows.Models;
 6
 7namespace Elsa.Workflows.Management.Mappers;
 8
 9/// <summary>
 10/// Maps <see cref="WorkflowDefinition"/> to and from <see cref="Workflow"/> and <see cref="WorkflowDefinitionModel"/>.
 11/// </summary>
 12public class WorkflowDefinitionMapper
 13{
 14    private readonly IActivitySerializer _activitySerializer;
 15    private readonly IWorkflowDefinitionService _workflowDefinitionService;
 16    private readonly VariableDefinitionMapper _variableDefinitionMapper;
 17
 18    /// <summary>
 19    /// Initializes a new instance of the <see cref="WorkflowDefinitionMapper"/> class.
 20    /// </summary>
 23121    public WorkflowDefinitionMapper(IActivitySerializer activitySerializer, IWorkflowDefinitionService workflowDefinitio
 22    {
 23123        _activitySerializer = activitySerializer;
 23124        _workflowDefinitionService = workflowDefinitionService;
 23125        _variableDefinitionMapper = variableDefinitionMapper;
 23126    }
 27
 28    /// <summary>
 29    /// Maps a <see cref="WorkflowDefinition"/> to a <see cref="Workflow"/>.
 30    /// </summary>
 31    /// <param name="source">The source <see cref="WorkflowDefinition"/>.</param>
 32    /// <returns>The mapped <see cref="Workflow"/>.</returns>
 33    public Workflow Map(WorkflowDefinition source)
 34    {
 35        // NEW WAY: If OriginalSource is present, deserialize the full WorkflowDefinitionModel
 36        // This enables symmetric round-trip without re-serialization
 84937        if (!string.IsNullOrEmpty(source.OriginalSource))
 38        {
 80339            var model = _activitySerializer.Deserialize<WorkflowDefinitionModel>(source.OriginalSource);
 80340            return MapFromModelWithIdentity(model, source);
 41        }
 42
 43        // OLD WAY: Deserialize from StringData (backwards compatibility)
 4644        var root = _activitySerializer.Deserialize(source.StringData!);
 45
 4646        return new(
 4647            new(source.DefinitionId, source.Version, source.Id, source.TenantId),
 4648            new(source.IsLatest, source.IsPublished),
 4649            new(source.Name, source.Description, source.CreatedAt, source.ToolVersion),
 4650            source.Options,
 4651            root,
 4652            source.Variables,
 4653            source.Inputs,
 4654            source.Outputs,
 4655            source.Outcomes,
 4656            source.CustomProperties,
 4657            source.IsReadonly,
 4658            source.IsSystem);
 59    }
 60
 61    /// <summary>
 62    /// Maps a <see cref="WorkflowDefinitionModel"/> to a <see cref="Workflow"/>, using identity from stored definition.
 63    /// </summary>
 64    private Workflow MapFromModelWithIdentity(WorkflowDefinitionModel model, WorkflowDefinition storedDefinition)
 65    {
 80366        var root = model.Root!;
 80367        var variables = _variableDefinitionMapper.Map(model.Variables).ToList();
 80368        var options = model.Options ?? new WorkflowOptions();
 69
 80370        return new(
 80371            new(storedDefinition.DefinitionId, storedDefinition.Version, storedDefinition.Id, storedDefinition.TenantId)
 80372            new(storedDefinition.IsLatest, storedDefinition.IsPublished),
 80373            new(model.Name, model.Description, model.CreatedAt, model.ToolVersion),
 80374            options,
 80375            root,
 80376            variables,
 80377            model.Inputs ?? new List<InputDefinition>(),
 80378            model.Outputs ?? new List<OutputDefinition>(),
 80379            model.Outcomes ?? new List<string>(),
 80380            model.CustomProperties ?? new Dictionary<string, object>(),
 80381            storedDefinition.IsReadonly,
 80382            storedDefinition.IsSystem);
 83    }
 84
 85    /// <summary>
 86    /// Maps a <see cref="WorkflowDefinitionModel"/> to a <see cref="Workflow"/>.
 87    /// </summary>
 88    /// <param name="source">The source <see cref="WorkflowDefinitionModel"/>.</param>
 89    /// <returns>The mapped <see cref="Workflow"/>.</returns>
 90    public Workflow Map(WorkflowDefinitionModel source)
 91    {
 130292        var root = source.Root!;
 130293        var variables = _variableDefinitionMapper.Map(source.Variables).ToList();
 130294        var options = source.Options ?? new WorkflowOptions();
 95
 96        // TODO: Remove this in the future when users have migrated workflows to use the new UsableAsActivity options pr
 97
 98#pragma warning disable CS0618
 130299        options.UsableAsActivity ??= source.UsableAsActivity ?? false;
 100#pragma warning restore CS0618
 101
 1302102        return new(
 1302103            new(source.DefinitionId, source.Version, source.Id, source.TenantId),
 1302104            new(source.IsLatest, source.IsPublished),
 1302105            new(source.Name, source.Description, source.CreatedAt, source.ToolVersion),
 1302106            options,
 1302107            root,
 1302108            variables,
 1302109            source.Inputs ?? new List<InputDefinition>(),
 1302110            source.Outputs ?? new List<OutputDefinition>(),
 1302111            source.Outcomes ?? new List<string>(),
 1302112            source.CustomProperties ?? new Dictionary<string, object>(),
 1302113            source.IsReadonly,
 1302114            source.IsSystem);
 115    }
 116
 117    public WorkflowDefinition MapToWorkflowDefinition(WorkflowDefinitionModel source)
 118    {
 0119        var root = source.Root!;
 0120        var variables = _variableDefinitionMapper.Map(source.Variables).ToList();
 0121        var options = source.Options ?? new WorkflowOptions();
 0122        var stringData = _activitySerializer.Serialize(root);
 123
 0124        return new()
 0125        {
 0126            IsPublished = source.IsPublished,
 0127            Description = source.Description,
 0128            Id = source.Id,
 0129            Inputs = source.Inputs ?? [],
 0130            Name = source.Name,
 0131            Options = options,
 0132            Outcomes = source.Outcomes ?? [],
 0133            Outputs = source.Outputs ?? [],
 0134            Variables = variables,
 0135            Version = source.Version,
 0136            CreatedAt = source.CreatedAt,
 0137            CustomProperties = source.CustomProperties ?? new Dictionary<string, object>(),
 0138            DefinitionId = source.DefinitionId,
 0139            IsLatest = source.IsLatest,
 0140            IsReadonly = source.IsReadonly,
 0141            IsSystem = source.IsSystem,
 0142            TenantId = source.TenantId,
 0143            ToolVersion = source.ToolVersion,
 0144            StringData = stringData,
 0145            MaterializerName = JsonWorkflowMaterializer.MaterializerName
 0146        };
 147    }
 148
 149    /// <summary>
 150    /// Maps many <see cref="WorkflowDefinition"/>s to many <see cref="WorkflowDefinitionModel"/>s.
 151    /// </summary>
 152    /// <param name="source">The source <see cref="WorkflowDefinition"/>s.</param>
 153    /// <param name="cancellationToken">An optional cancellation token.</param>
 154    /// <returns>The mapped <see cref="WorkflowDefinitionModel"/>s.</returns>
 155    public async Task<IEnumerable<WorkflowDefinitionModel>> MapAsync(IEnumerable<WorkflowDefinition> source, Cancellatio
 156    {
 0157        return await Task.WhenAll(source.Select(async x => await MapAsync(x, cancellationToken)));
 0158    }
 159
 160    /// <summary>
 161    /// Maps a <see cref="WorkflowDefinition"/> to a <see cref="Workflow"/>.
 162    /// </summary>
 163    /// <param name="workflowDefinition">The source <see cref="WorkflowDefinition"/>.</param>
 164    /// <param name="cancellationToken">The cancellation token.</param>
 165    /// <returns>The mapped <see cref="Workflow"/>.</returns>
 166    public async Task<WorkflowDefinitionModel> MapAsync(WorkflowDefinition workflowDefinition, CancellationToken cancell
 167    {
 1168        var workflowGraph = await _workflowDefinitionService.MaterializeWorkflowAsync(workflowDefinition, cancellationTo
 1169        var workflow = workflowGraph.Workflow;
 1170        var variables = _variableDefinitionMapper.Map(workflow.Variables).ToList();
 171
 1172        return new(
 1173            workflowDefinition.Id,
 1174            workflowDefinition.DefinitionId,
 1175            workflowDefinition.TenantId,
 1176            workflowDefinition.Name,
 1177            workflowDefinition.Description,
 1178            workflowDefinition.CreatedAt,
 1179            workflowDefinition.Version,
 1180            workflowDefinition.ToolVersion,
 1181            variables,
 1182            workflowDefinition.Inputs,
 1183            workflowDefinition.Outputs,
 1184            workflowDefinition.Outcomes,
 1185            workflowDefinition.CustomProperties,
 1186            workflowDefinition.IsReadonly,
 1187            workflowDefinition.IsSystem,
 1188            workflowDefinition.IsLatest,
 1189            workflowDefinition.IsPublished,
 1190            workflow.Options,
 1191            null,
 1192            workflow.Root);
 1193    }
 194
 195    /// <summary>
 196    /// Maps a <see cref="Workflow"/> to a <see cref="WorkflowDefinitionModel"/>.
 197    /// </summary>
 198    /// <param name="workflow">The source <see cref="WorkflowDefinition"/>.</param>
 199    /// <returns>The mapped <see cref="WorkflowDefinitionModel"/>.</returns>
 200    public WorkflowDefinitionModel Map(Workflow workflow)
 201    {
 0202        var variables = _variableDefinitionMapper.Map(workflow.Variables).ToList();
 203
 0204        return new(
 0205            workflow.Identity.Id,
 0206            workflow.Identity.DefinitionId,
 0207            workflow.Identity.TenantId,
 0208            workflow.WorkflowMetadata.Name,
 0209            workflow.WorkflowMetadata.Description,
 0210            workflow.WorkflowMetadata.CreatedAt,
 0211            workflow.Identity.Version,
 0212            workflow.WorkflowMetadata.ToolVersion,
 0213            variables,
 0214            workflow.Inputs,
 0215            workflow.Outputs,
 0216            workflow.Outcomes,
 0217            workflow.CustomProperties,
 0218            workflow.IsReadonly,
 0219            workflow.IsSystem,
 0220            workflow.Publication.IsLatest,
 0221            workflow.Publication.IsPublished,
 0222            workflow.Options,
 0223            null,
 0224            workflow.Root);
 225    }
 226}