< 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: 229
Line coverage: 61%
Branch coverage
72%
Covered branches: 26
Total branches: 36
Branch coverage: 72.2%
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%44100%
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>
 36421    public WorkflowDefinitionMapper(IActivitySerializer activitySerializer, IWorkflowDefinitionService workflowDefinitio
 22    {
 36423        _activitySerializer = activitySerializer;
 36424        _workflowDefinitionService = workflowDefinitionService;
 36425        _variableDefinitionMapper = variableDefinitionMapper;
 36426    }
 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        // OriginalSource is the authoritative payload only when StringData is absent
 36        // (ElsaScript, YAML, and other source-only materializers introduced with #7076).
 37        // File-imported JSON stores both: the blob snapshot in OriginalSource and the
 38        // serialized root in StringData. Studio/API edits update StringData (and entity
 39        // fields) but used to leave OriginalSource stale, so preferring OriginalSource
 40        // silently ignored those edits at export and execution. See #8305.
 89041        if (string.IsNullOrEmpty(source.StringData) && !string.IsNullOrEmpty(source.OriginalSource))
 42        {
 143            var model = _activitySerializer.Deserialize<WorkflowDefinitionModel>(source.OriginalSource);
 144            return MapFromModelWithIdentity(model, source);
 45        }
 46
 88947        var root = _activitySerializer.Deserialize(source.StringData!);
 48
 88949        return new(
 88950            new(source.DefinitionId, source.Version, source.Id, source.TenantId),
 88951            new(source.IsLatest, source.IsPublished),
 88952            new(source.Name, source.Description, source.CreatedAt, source.ToolVersion),
 88953            source.Options,
 88954            root,
 88955            source.Variables,
 88956            source.Inputs,
 88957            source.Outputs,
 88958            source.Outcomes,
 88959            source.CustomProperties,
 88960            source.IsReadonly,
 88961            source.IsSystem);
 62    }
 63
 64    /// <summary>
 65    /// Maps a <see cref="WorkflowDefinitionModel"/> to a <see cref="Workflow"/>, using identity from stored definition.
 66    /// </summary>
 67    private Workflow MapFromModelWithIdentity(WorkflowDefinitionModel model, WorkflowDefinition storedDefinition)
 68    {
 169        var root = model.Root!;
 170        var variables = _variableDefinitionMapper.Map(model.Variables).ToList();
 171        var options = model.Options ?? new WorkflowOptions();
 72
 173        return new(
 174            new(storedDefinition.DefinitionId, storedDefinition.Version, storedDefinition.Id, storedDefinition.TenantId)
 175            new(storedDefinition.IsLatest, storedDefinition.IsPublished),
 176            new(model.Name, model.Description, model.CreatedAt, model.ToolVersion),
 177            options,
 178            root,
 179            variables,
 180            model.Inputs ?? new List<InputDefinition>(),
 181            model.Outputs ?? new List<OutputDefinition>(),
 182            model.Outcomes ?? new List<string>(),
 183            model.CustomProperties ?? new Dictionary<string, object>(),
 184            storedDefinition.IsReadonly,
 185            storedDefinition.IsSystem);
 86    }
 87
 88    /// <summary>
 89    /// Maps a <see cref="WorkflowDefinitionModel"/> to a <see cref="Workflow"/>.
 90    /// </summary>
 91    /// <param name="source">The source <see cref="WorkflowDefinitionModel"/>.</param>
 92    /// <returns>The mapped <see cref="Workflow"/>.</returns>
 93    public Workflow Map(WorkflowDefinitionModel source)
 94    {
 93695        var root = source.Root!;
 93696        var variables = _variableDefinitionMapper.Map(source.Variables).ToList();
 93697        var options = source.Options ?? new WorkflowOptions();
 98
 99        // TODO: Remove this in the future when users have migrated workflows to use the new UsableAsActivity options pr
 100
 101#pragma warning disable CS0618
 936102        options.UsableAsActivity ??= source.UsableAsActivity ?? false;
 103#pragma warning restore CS0618
 104
 936105        return new(
 936106            new(source.DefinitionId, source.Version, source.Id, source.TenantId),
 936107            new(source.IsLatest, source.IsPublished),
 936108            new(source.Name, source.Description, source.CreatedAt, source.ToolVersion),
 936109            options,
 936110            root,
 936111            variables,
 936112            source.Inputs ?? new List<InputDefinition>(),
 936113            source.Outputs ?? new List<OutputDefinition>(),
 936114            source.Outcomes ?? new List<string>(),
 936115            source.CustomProperties ?? new Dictionary<string, object>(),
 936116            source.IsReadonly,
 936117            source.IsSystem);
 118    }
 119
 120    public WorkflowDefinition MapToWorkflowDefinition(WorkflowDefinitionModel source)
 121    {
 0122        var root = source.Root!;
 0123        var variables = _variableDefinitionMapper.Map(source.Variables).ToList();
 0124        var options = source.Options ?? new WorkflowOptions();
 0125        var stringData = _activitySerializer.Serialize(root);
 126
 0127        return new()
 0128        {
 0129            IsPublished = source.IsPublished,
 0130            Description = source.Description,
 0131            Id = source.Id,
 0132            Inputs = source.Inputs ?? [],
 0133            Name = source.Name,
 0134            Options = options,
 0135            Outcomes = source.Outcomes ?? [],
 0136            Outputs = source.Outputs ?? [],
 0137            Variables = variables,
 0138            Version = source.Version,
 0139            CreatedAt = source.CreatedAt,
 0140            CustomProperties = source.CustomProperties ?? new Dictionary<string, object>(),
 0141            DefinitionId = source.DefinitionId,
 0142            IsLatest = source.IsLatest,
 0143            IsReadonly = source.IsReadonly,
 0144            IsSystem = source.IsSystem,
 0145            TenantId = source.TenantId,
 0146            ToolVersion = source.ToolVersion,
 0147            StringData = stringData,
 0148            MaterializerName = JsonWorkflowMaterializer.MaterializerName
 0149        };
 150    }
 151
 152    /// <summary>
 153    /// Maps many <see cref="WorkflowDefinition"/>s to many <see cref="WorkflowDefinitionModel"/>s.
 154    /// </summary>
 155    /// <param name="source">The source <see cref="WorkflowDefinition"/>s.</param>
 156    /// <param name="cancellationToken">An optional cancellation token.</param>
 157    /// <returns>The mapped <see cref="WorkflowDefinitionModel"/>s.</returns>
 158    public async Task<IEnumerable<WorkflowDefinitionModel>> MapAsync(IEnumerable<WorkflowDefinition> source, Cancellatio
 159    {
 0160        return await Task.WhenAll(source.Select(async x => await MapAsync(x, cancellationToken)));
 0161    }
 162
 163    /// <summary>
 164    /// Maps a <see cref="WorkflowDefinition"/> to a <see cref="Workflow"/>.
 165    /// </summary>
 166    /// <param name="workflowDefinition">The source <see cref="WorkflowDefinition"/>.</param>
 167    /// <param name="cancellationToken">The cancellation token.</param>
 168    /// <returns>The mapped <see cref="Workflow"/>.</returns>
 169    public async Task<WorkflowDefinitionModel> MapAsync(WorkflowDefinition workflowDefinition, CancellationToken cancell
 170    {
 12171        var workflowGraph = await _workflowDefinitionService.MaterializeWorkflowAsync(workflowDefinition, cancellationTo
 12172        var workflow = workflowGraph.Workflow;
 12173        var variables = _variableDefinitionMapper.Map(workflow.Variables).ToList();
 174
 12175        return new(
 12176            workflowDefinition.Id,
 12177            workflowDefinition.DefinitionId,
 12178            workflowDefinition.TenantId,
 12179            workflowDefinition.Name,
 12180            workflowDefinition.Description,
 12181            workflowDefinition.CreatedAt,
 12182            workflowDefinition.Version,
 12183            workflowDefinition.ToolVersion,
 12184            variables,
 12185            workflowDefinition.Inputs,
 12186            workflowDefinition.Outputs,
 12187            workflowDefinition.Outcomes,
 12188            workflowDefinition.CustomProperties,
 12189            workflowDefinition.IsReadonly,
 12190            workflowDefinition.IsSystem,
 12191            workflowDefinition.IsLatest,
 12192            workflowDefinition.IsPublished,
 12193            workflow.Options,
 12194            null,
 12195            workflow.Root);
 12196    }
 197
 198    /// <summary>
 199    /// Maps a <see cref="Workflow"/> to a <see cref="WorkflowDefinitionModel"/>.
 200    /// </summary>
 201    /// <param name="workflow">The source <see cref="WorkflowDefinition"/>.</param>
 202    /// <returns>The mapped <see cref="WorkflowDefinitionModel"/>.</returns>
 203    public WorkflowDefinitionModel Map(Workflow workflow)
 204    {
 0205        var variables = _variableDefinitionMapper.Map(workflow.Variables).ToList();
 206
 0207        return new(
 0208            workflow.Identity.Id,
 0209            workflow.Identity.DefinitionId,
 0210            workflow.Identity.TenantId,
 0211            workflow.WorkflowMetadata.Name,
 0212            workflow.WorkflowMetadata.Description,
 0213            workflow.WorkflowMetadata.CreatedAt,
 0214            workflow.Identity.Version,
 0215            workflow.WorkflowMetadata.ToolVersion,
 0216            variables,
 0217            workflow.Inputs,
 0218            workflow.Outputs,
 0219            workflow.Outcomes,
 0220            workflow.CustomProperties,
 0221            workflow.IsReadonly,
 0222            workflow.IsSystem,
 0223            workflow.Publication.IsLatest,
 0224            workflow.Publication.IsPublished,
 0225            workflow.Options,
 0226            null,
 0227            workflow.Root);
 228    }
 229}