From e51395ff212a45f00f7dc9b83588dd5943146f1f Mon Sep 17 00:00:00 2001 From: Joseph Stewart Date: Sat, 31 Jul 2021 18:35:10 -0700 Subject: [PATCH] Add test for javascript --- .../Handlers/ConfigureJavaScriptEngine.cs | 5 +- .../JavaScriptExpressionsIntegrationTests.cs | 87 +++++++++++++++++++ .../Helpers/AssertableActivityState.cs | 9 ++ 3 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 test/shared/Elsa.Testing.Shared/Helpers/AssertableActivityState.cs diff --git a/src/scripting/Elsa.Scripting.JavaScript/Handlers/ConfigureJavaScriptEngine.cs b/src/scripting/Elsa.Scripting.JavaScript/Handlers/ConfigureJavaScriptEngine.cs index 37c049576..e86962b79 100644 --- a/src/scripting/Elsa.Scripting.JavaScript/Handlers/ConfigureJavaScriptEngine.cs +++ b/src/scripting/Elsa.Scripting.JavaScript/Handlers/ConfigureJavaScriptEngine.cs @@ -16,6 +16,7 @@ using Elsa.Services.WorkflowStorage; using Jint; using MediatR; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Options; using NodaTime; namespace Elsa.Scripting.JavaScript.Handlers @@ -27,12 +28,12 @@ namespace Elsa.Scripting.JavaScript.Handlers private readonly IWorkflowStorageService _workflowStorageService; private readonly ScriptOptions _scriptOptions; - public ConfigureJavaScriptEngine(IConfiguration configuration, IActivityTypeService activityTypeService, IWorkflowStorageService workflowStorageService, ScriptOptions scriptOptions) + public ConfigureJavaScriptEngine(IConfiguration configuration, IActivityTypeService activityTypeService, IWorkflowStorageService workflowStorageService, IOptions scriptOptions) { _configuration = configuration; _activityTypeService = activityTypeService; _workflowStorageService = workflowStorageService; - _scriptOptions = scriptOptions; + _scriptOptions = scriptOptions.Value; } public async Task Handle(EvaluatingJavaScriptExpression notification, CancellationToken cancellationToken) diff --git a/test/integration/Elsa.Core.IntegrationTests/Scripting/JavaScript/JavaScriptExpressionsIntegrationTests.cs b/test/integration/Elsa.Core.IntegrationTests/Scripting/JavaScript/JavaScriptExpressionsIntegrationTests.cs index dda238500..efdd967ae 100644 --- a/test/integration/Elsa.Core.IntegrationTests/Scripting/JavaScript/JavaScriptExpressionsIntegrationTests.cs +++ b/test/integration/Elsa.Core.IntegrationTests/Scripting/JavaScript/JavaScriptExpressionsIntegrationTests.cs @@ -1,14 +1,19 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using Elsa.Activities.Console; using Elsa.Activities.Primitives; +using Elsa.ActivityResults; +using Elsa.Builders; using Elsa.Core.IntegrationTests.Autofixture; +using Elsa.Expressions; using Elsa.Models; using Elsa.Serialization; using Elsa.Services; using Elsa.Services.Models; using Elsa.Testing.Shared; using Elsa.Testing.Shared.Helpers; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Xunit; @@ -25,6 +30,88 @@ namespace Elsa.Core.IntegrationTests.Scripting.JavaScript var host = await hostBuilder.StartAsync(); } + [Fact(DisplayName = "JavaScript expressions cannot access configuration by default")] + public async Task JavaScriptCannotAccessConfigurationByDefault() + { + var services = new ServiceCollection() + .AddSingleton(_ => new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + { "SomeSecret", "I am a secret" }, + }) + .Build()) + .AddSingleton() + .AddElsa(elsa => elsa + .AddActivity() + .AddWorkflow()) + .BuildServiceProvider(); + + var workflowStarter = services.GetRequiredService(); + var activityState = services.GetRequiredService(); + + await workflowStarter.BuildAndStartWorkflowAsync(); + + Assert.Single(activityState.Messages, "Config secret: "); + } + + [Fact(DisplayName = "JavaScript expressions can have configuration access enabled")] + public async Task JavaScriptExpressionsHaveConfigurationAccessEnabled() + { + var services = new ServiceCollection() + .AddSingleton(_ => new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + { "SomeSecret", "I am a secret" }, + }) + .Build()) + .AddSingleton() + .AddElsa(elsa => elsa + .AddActivity() + .AddWorkflow()) + .WithJavaScriptOptions(x => + { + x.EnableConfigurationAccess = true; + }) + .BuildServiceProvider(); + + var workflowStarter = services.GetRequiredService(); + var activityState = services.GetRequiredService(); + + await workflowStarter.BuildAndStartWorkflowAsync(); + + Assert.Single(activityState.Messages, "Config secret: I am a secret"); + } + + private class ConfigurationAccessWorkflow : IWorkflow + { + public void Build(IWorkflowBuilder builder) + { + builder.StartWith(); + } + } + + private class WriteConfigActivity : Activity + { + private IExpressionEvaluator _expressionEvaluator; + private AssertableActivityState _activityState; + + public WriteConfigActivity(IExpressionEvaluator evaluator, AssertableActivityState activityState) + { + _expressionEvaluator = evaluator; + _activityState = activityState; + } + + protected override async ValueTask OnExecuteAsync(ActivityExecutionContext context) + { + var javaScriptExpression = "getConfig('SomeSecret')"; + var expressionResult = await _expressionEvaluator.TryEvaluateAsync(javaScriptExpression, "JavaScript", context); + + _activityState.Messages.Add($"Config secret: {expressionResult.Value ?? ""}"); + + return Done(); + } + } + private class HostedWorkflowRunner : IHostedService { private readonly IStartsWorkflow _workflowRunner; diff --git a/test/shared/Elsa.Testing.Shared/Helpers/AssertableActivityState.cs b/test/shared/Elsa.Testing.Shared/Helpers/AssertableActivityState.cs new file mode 100644 index 000000000..9661101ea --- /dev/null +++ b/test/shared/Elsa.Testing.Shared/Helpers/AssertableActivityState.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Elsa.Testing.Shared.Helpers +{ + public class AssertableActivityState + { + public List Messages { get; set; } = new(); + } +} \ No newline at end of file