diff --git a/ActionFlow.Tests/ActionFlow.Tests.csproj b/ActionFlow.Tests/ActionFlow.Tests.csproj
index aaf7cd2..b193972 100644
--- a/ActionFlow.Tests/ActionFlow.Tests.csproj
+++ b/ActionFlow.Tests/ActionFlow.Tests.csproj
@@ -10,6 +10,7 @@
+
@@ -24,4 +25,10 @@
+
+
+ Always
+
+
+
diff --git a/ActionFlow.Tests/Actions/CallWorkflowActionTests.cs b/ActionFlow.Tests/Actions/CallWorkflowActionTests.cs
index 6fa2099..7134e55 100644
--- a/ActionFlow.Tests/Actions/CallWorkflowActionTests.cs
+++ b/ActionFlow.Tests/Actions/CallWorkflowActionTests.cs
@@ -1,4 +1,5 @@
using ActionFlow.Actions;
+using ActionFlow.Domain.Actions;
using ActionFlow.Domain.Engine;
using ActionFlow.Engine;
using ActionFlow.Engine.Factories;
@@ -7,71 +8,70 @@
namespace ActionFlow.Tests.Actions
{
- [TestClass]
- public class CallWorkflowActionTests
- {
- [TestMethod]
- public async Task When_executing_it_should_call_other_workflow_and_get_output_variable()
- {
- //Arrange
- var workflowProvider = Substitute.For();
- var workflows = CreateFakeWorkflowsWithOutput();
- workflowProvider.GetAllWorkflows().Returns(workflows);
+ [TestClass]
+ public class CallWorkflowActionTests
+ {
+ [TestMethod]
+ public async Task When_executing_it_should_call_other_workflow_and_get_output_variable()
+ {
+ //Arrange
+ var workflowProvider = Substitute.For();
+ var workflows = CreateFakeWorkflowsWithOutput();
+ workflowProvider.GetAllWorkflows().Returns(workflows);
- var stepActionFactory = Substitute.For();
- stepActionFactory.Get("Variable").Returns(new SetVariableAction());
+ var stepActionFactory = Substitute.For();
+ stepActionFactory.Get("Variable").Returns(new SetVariableAction());
- var stepExecutionEvaluator = new StepExecutionEvaluator();
+ var stepExecutionEvaluator = new StepExecutionEvaluator();
+ var actionFlowEngine = new ActionFlowEngine(workflowProvider, stepActionFactory, stepExecutionEvaluator);
- var actionFlowEngine = new ActionFlowEngine(workflowProvider, stepActionFactory, stepExecutionEvaluator);
+ var sut = new CallWorkflowAction();
+ var executionContext = new ActionFlow.Engine.ExecutionContext(actionFlowEngine);
+ var parameters = new Dictionary
+ {
+ { "age", "18" }
+ };
+ var targetWorkflowName = "Test Workflow Rule 2";
+ var resultVariableName = "result";
+ executionContext.AddOrUpdateActionProperty(CallWorkflowAction.WorkflowNameKey, targetWorkflowName);
+ executionContext.AddOrUpdateActionProperty(CallWorkflowAction.ResultVariableKey, resultVariableName);
+ executionContext.AddOrUpdateActionProperty(CallWorkflowAction.ParametersKey, parameters);
+ sut.SetExecutionContext(executionContext);
- var sut = new CallWorkflowAction();
- var executionContext = new ActionFlow.Engine.ExecutionContext(actionFlowEngine);
- var parameters = new Dictionary
- {
- { "age", "18" }
- };
- var targetWorkflowName = "Test Workflow Rule 2";
- var resultVariableName = "result";
- executionContext.AddOrUpdateActionProperty(CallWorkflowAction.WorkflowNameKey, targetWorkflowName);
- executionContext.AddOrUpdateActionProperty(CallWorkflowAction.ResultVariableKey, resultVariableName);
- executionContext.AddOrUpdateActionProperty(CallWorkflowAction.ParametersKey, parameters);
- sut.SetExecutionContext(executionContext);
+ //Act
+ await sut.ExecuteAction();
- //Act
- await sut.ExecuteAction();
+ //Assert
+ var output = executionContext.EvaluateExpression>(resultVariableName);
+ Assert.AreEqual(true, output["canVote"]);
+ }
- //Assert
- var output = executionContext.EvaluateExpression>(resultVariableName);
- Assert.IsTrue((bool)output["canVote"]);
- }
+ private static List CreateFakeWorkflowsWithOutput()
+ {
+ List workflows = [];
- private static List CreateFakeWorkflowsWithOutput()
- {
- List workflows = [];
+ var targetWorkflowName = "Test Workflow Rule 2";
- var targetWorkflowName = "Test Workflow Rule 2";
+ var steps2 = new List
+ {
+ new("test variable value", "Variable", new Dictionary
+ {
+ {
+ SetVariableAction.VariablesKey, new Dictionary
+ {
+ { "canVote", "age >= 18" }
+ }
+ }
+ })
+ };
- var steps2 = new List
- {
- new("test variable value", "Variable", new Dictionary
- {
- {
- SetVariableAction.VariablesKey, new Dictionary
- {
- { "canVote", "age >= 18" }
- }
- }
- })
- };
-
- Workflow workflow2 = new Workflow(targetWorkflowName, steps2,
+ Workflow workflow2 = new Workflow(targetWorkflowName, steps2,
[
- new Parameter{ Name = "canVote", Expression = "canVote"}
- ]);
- workflows.Add(workflow2);
+ new() { Name = "canVote", Expression = "canVote"}
+ ]);
+ workflows.Add(workflow2);
- return workflows;
- }
- }
+ return workflows;
+ }
+ }
}
diff --git a/ActionFlow.Tests/Actions/ControlFlowActionTests.cs b/ActionFlow.Tests/Actions/ControlFlowActionTests.cs
index 4dee0c8..b264a6c 100644
--- a/ActionFlow.Tests/Actions/ControlFlowActionTests.cs
+++ b/ActionFlow.Tests/Actions/ControlFlowActionTests.cs
@@ -1,138 +1,137 @@
using ActionFlow.Actions;
using ActionFlow.Domain.Actions;
-using ActionFlow.Domain.Engine;
using ActionFlow.Engine;
-using ActionFlow.Engine.Factories;
using NSubstitute;
namespace ActionFlow.Tests.Actions
{
- [TestClass]
- public class ControlFlowActionTests : ActionBaseTests
- {
- [TestMethod]
- public async Task When_executing_it_should_call_only_valid_scoped_workflow_steps()
- {
- //Arrange
- var sut = new ControlFlowAction();
- var stepExecutionEvaluator = new StepExecutionEvaluator();
- ActionFlowEngine.GetStepExecutionEvaluator().Returns(stepExecutionEvaluator);
- var executionContext = ExecutionContext;
+ [TestClass]
+ public class ControlFlowActionTests : ActionBaseTests
+ {
+ [TestMethod]
+ public async Task When_executing_it_should_call_only_valid_scoped_workflow_steps()
+ {
+ //Arrange
+ var sut = new ControlFlowAction();
+ var stepExecutionEvaluator = new StepExecutionEvaluator();
+ ActionFlowEngine.GetStepExecutionEvaluator().Returns(stepExecutionEvaluator);
+ var executionContext = ExecutionContext;
- var conditions = CreateScopedWorkflows();
- executionContext.AddOrUpdateParameter("age", 18);
- executionContext.AddOrUpdateActionProperty(ControlFlowAction.ConditionsKey, conditions);
- sut.SetExecutionContext(executionContext);
+ var conditions = CreateScopedWorkflows();
+ executionContext.AddOrUpdateParameter("age", 18);
+ executionContext.AddOrUpdateActionProperty(ControlFlowAction.ConditionsKey, conditions);
+ sut.SetExecutionContext(executionContext);
- //Act
- await sut.ExecuteAction();
+ //Act
+ await sut.ExecuteAction();
- //Assert
- Assert.AreEqual(18, executionContext.EvaluateExpression("age"));
- Assert.AreEqual(true, executionContext.EvaluateExpression("canWalk"));
- }
+ //Assert
+ Assert.AreEqual(18, executionContext.EvaluateExpression("age"));
+ Assert.IsTrue(executionContext.EvaluateExpression("canWalk"));
+ }
- [TestMethod]
- public async Task When_executing_it_should_call_all_scoped_workflow_steps()
- {
- //Arrange
- var sut = new ControlFlowAction();
- var stepExecutionEvaluator = new StepExecutionEvaluator();
- ActionFlowEngine.GetStepExecutionEvaluator().Returns(stepExecutionEvaluator);
- var executionContext = ExecutionContext;
+ [TestMethod]
+ public async Task When_executing_it_should_call_all_scoped_workflow_steps()
+ {
+ //Arrange
+ var sut = new ControlFlowAction();
+ var stepExecutionEvaluator = new StepExecutionEvaluator();
+ ActionFlowEngine.GetStepExecutionEvaluator().Returns(stepExecutionEvaluator);
+ var executionContext = ExecutionContext;
- var conditions = CreateScopedWorkflowsThatAllWillBeCalled();
- executionContext.AddOrUpdateParameter("age", 1);
- executionContext.AddOrUpdateActionProperty(ControlFlowAction.ConditionsKey, conditions);
- sut.SetExecutionContext(executionContext);
+ var conditions = CreateScopedWorkflowsThatAllWillBeCalled();
+ executionContext.AddOrUpdateParameter("age", 1);
+ executionContext.AddOrUpdateActionProperty(ControlFlowAction.ConditionsKey, conditions);
+ sut.SetExecutionContext(executionContext);
- //Act
- await sut.ExecuteAction();
+ //Act
+ await sut.ExecuteAction();
- //Assert
- Assert.AreEqual(true, executionContext.EvaluateExpression("isBaby"));
- Assert.AreEqual(18, executionContext.EvaluateExpression("age"));
- Assert.AreEqual(true, executionContext.EvaluateExpression("canWalk"));
- }
+ //Assert
+ Assert.IsTrue(executionContext.EvaluateExpression("isBaby"));
+ Assert.AreEqual(18, executionContext.EvaluateExpression("age"));
+ Assert.IsTrue(executionContext.EvaluateExpression("canWalk"));
+ }
- private static List CreateScopedWorkflows()
- {
- var conditions = new List
- {
- new() {
- Expression = "age == 1",
- Steps =
+ private static List CreateScopedWorkflows()
+ {
+ var conditions = new List
+ {
+ new() {
+ Expression = "age == 1",
+ Steps =
[
- new Step("Set canWalk to false", "Variable", new Dictionary
- {
- {
- SetVariableAction.VariablesKey, new Dictionary
- {
- { "canWalk", "false" }
- }
- }
- })
- ]
- },
- new() {
- Expression = "age == 18",
- Steps =
+ new ("Set canWalk to false", "Variable", new Dictionary
+ {
+ {
+ SetVariableAction.VariablesKey, new Dictionary
+ {
+ { "canWalk", "false" }
+ }
+ }
+ })
+ ]
+ },
+ new() {
+ Expression = "age == 18",
+ Steps =
[
- new Step("Set canWalk to true", "Variable", new Dictionary
- {
- {
- SetVariableAction.VariablesKey, new Dictionary
- {
- { "canWalk", "true" }
- }
- }
- })
- ]
- }
- };
+ new("Set canWalk to true", "Variable", new Dictionary
+ {
+ {
+ SetVariableAction.VariablesKey, new Dictionary
+ {
+ { "canWalk", "true" }
+ }
+ }
+ })
+ ]
+ }
+ };
- return conditions;
- }
+ return conditions;
+ }
- private static List CreateScopedWorkflowsThatAllWillBeCalled()
- {
- var conditions = new List
- {
- new() {
- Expression = "age == 1",
- Steps =
+ private static List CreateScopedWorkflowsThatAllWillBeCalled()
+ {
+ var conditions = new List
+ {
+ new() {
+ Expression = "age == 1",
+ Steps =
[
- new Step("Set canWalk to false", "Variable", new Dictionary
- {
- {
- SetVariableAction.VariablesKey, new Dictionary
- {
- { "canWalk", "false" },
- { "isBaby", "true" },
- { "age", "18" }
- }
- }
- })
- ]
- },
- new() {
- Expression = "age == 18",
- Steps =
+ new("Set canWalk to false", "Variable", new Dictionary
+ {
+ {
+ SetVariableAction.VariablesKey, new Dictionary
+ {
+ { "canWalk", "false" },
+ { "isBaby", "true" },
+ { "age", "18" }
+ }
+ }
+ })
+ ]
+ },
+ new() {
+ Expression = "age == 18",
+ Steps =
[
- new Step("Set canWalk to true", "Variable", new Dictionary
- {
- {
- SetVariableAction.VariablesKey, new Dictionary
- {
- { "canWalk", "true" }
- }
- }
- })
- ]
- }
- };
+ new("Set canWalk to true", "Variable", new Dictionary
+ {
+ {
+ SetVariableAction.VariablesKey, new Dictionary
+ {
+ { "canWalk", "true" }
+ }
+ }
+ })
+ ]
+ }
+ };
- return conditions;
- }
- }
+
+ return conditions;
+ }
+ }
}
diff --git a/ActionFlow.Tests/Actions/ForLoopActionTests.cs b/ActionFlow.Tests/Actions/ForLoopActionTests.cs
index 57c5996..39644c9 100644
--- a/ActionFlow.Tests/Actions/ForLoopActionTests.cs
+++ b/ActionFlow.Tests/Actions/ForLoopActionTests.cs
@@ -34,20 +34,20 @@ public async Task When_executing_it_should_repeat_steps_3_times()
Assert.AreEqual(21, executionContext.EvaluateExpression("age"));
}
- private static List CreateLoopSteps()
- {
- var steps = new List
- {
- new("Increment age by 1", "Variable", new Dictionary
- {
- {
- SetVariableAction.VariablesKey, new Dictionary
- {
- { "age", "age + 1" }
- }
- }
- })
- };
+ private static List CreateLoopSteps()
+ {
+ var steps = new List
+ {
+ new("Increment age by 1", "Variable", new Dictionary
+ {
+ {
+ SetVariableAction.VariablesKey, new Dictionary
+ {
+ { "age", "age + 1" }
+ }
+ }
+ })
+ };
return steps;
}
diff --git a/ActionFlow.Tests/Engine/ActionFlowEngineTests.cs b/ActionFlow.Tests/Engine/ActionFlowEngineTests.cs
index f133697..225b6e7 100644
--- a/ActionFlow.Tests/Engine/ActionFlowEngineTests.cs
+++ b/ActionFlow.Tests/Engine/ActionFlowEngineTests.cs
@@ -7,97 +7,97 @@
namespace ActionFlow.Tests.Engine
{
- [TestClass]
- public class ActionFlowEngineTests
- {
- [TestMethod]
- public async Task When_running_rule_engine_with_basic_workflow_it_should_execute()
- {
- //Arrange
- var workflowProvider = Substitute.For();
- var workflows = CreateFakeWorkflows();
- workflowProvider.GetAllWorkflows().Returns(workflows);
-
- var stepActionFactory = Substitute.For();
- var stepExecutionEvaluator = Substitute.For();
-
- var actionFlowEngine = new ActionFlowEngine(workflowProvider, stepActionFactory, stepExecutionEvaluator);
-
- var inputs = new Parameter[]
- {
- new() { Name = "test", Expression = "true"}
- };
-
- //Act
- await actionFlowEngine.ExecuteWorkflowAsync("Test Workflow Rule 1", inputs);
-
- //Assert
- await stepExecutionEvaluator.ReceivedWithAnyArgs(2).EvaluateAndRunStep(workflows[0].Steps[0], new ExecutionContext(actionFlowEngine), stepActionFactory);
- }
-
- [TestMethod]
- public async Task When_running_rule_engine_with_output_parameter_workflow_it_evaluate_output()
- {
- //Arrange
- var workflowProvider = Substitute.For();
- var workflows = CreateFakeWorkflowsWithOutput();
- workflowProvider.GetAllWorkflows().Returns(workflows);
-
- var stepActionFactory = Substitute.For();
- var stepExecutionEvaluator = Substitute.For();
- var actionFlowEngine = new ActionFlowEngine(workflowProvider, stepActionFactory, stepExecutionEvaluator);
-
- var executionContext = new ExecutionContext(actionFlowEngine);
- executionContext.AddOrUpdateParameter(new Parameter { Name = "age", Expression = "1" });
- executionContext.AddOrUpdateParameter(new Parameter { Name = "canWalk", Expression = "true" });
-
- stepExecutionEvaluator.EvaluateAndRunStep(workflows[0].Steps[0], executionContext, stepActionFactory).ReturnsForAnyArgs(executionContext);
-
- //Act
- var output = await actionFlowEngine.ExecuteWorkflowAsync("Test Workflow Rule 1", executionContext);
-
- //Assert
- await stepExecutionEvaluator.ReceivedWithAnyArgs(1).EvaluateAndRunStep(workflows[0].Steps[0], new ExecutionContext(actionFlowEngine), stepActionFactory);
- Assert.AreEqual(2, output.OutputParameters.Count);
- Assert.IsFalse((bool)output.OutputParameters["canVote"]);
- Assert.AreEqual(1, output.OutputParameters["age"]);
- }
-
- private static List CreateFakeWorkflows()
- {
- List workflows = [];
- var steps = new List
- {
- new("initialize", "Variable", new Dictionary
- {
- { "age", "1" },
- { "canWalk", "true" },
- }),
- new("test variable value", "Variable", [], "age == 1 && canWalk == true")
- };
-
- Workflow workflow = new Workflow("Test Workflow Rule 1", steps);
- workflows.Add(workflow);
-
- return workflows;
- }
-
- private static List CreateFakeWorkflowsWithOutput()
- {
- List workflows = [];
- var steps = new List
- {
- new("test variable value", "Variable", [], "age == 1 && canWalk == true")
- };
-
- Workflow workflow = new Workflow("Test Workflow Rule 1", steps,
+ [TestClass]
+ public class ActionFlowEngineTests
+ {
+ [TestMethod]
+ public async Task When_running_rule_engine_with_basic_workflow_it_should_execute()
+ {
+ //Arrange
+ var workflowProvider = Substitute.For();
+ var workflows = CreateFakeWorkflows();
+ workflowProvider.GetAllWorkflows().Returns(workflows);
+
+ var stepActionFactory = Substitute.For();
+ var stepExecutionEvaluator = Substitute.For();
+
+ var actionFlowEngine = new ActionFlowEngine(workflowProvider, stepActionFactory, stepExecutionEvaluator);
+
+ var inputs = new Parameter[]
+ {
+ new() { Name = "test", Expression = "true"}
+ };
+
+ //Act
+ await actionFlowEngine.ExecuteWorkflowAsync("Test Workflow Rule 1", inputs);
+
+ //Assert
+ await stepExecutionEvaluator.ReceivedWithAnyArgs(2).EvaluateAndRunStep(workflows[0].Steps[0], new ExecutionContext(actionFlowEngine), stepActionFactory);
+ }
+
+ [TestMethod]
+ public async Task When_running_rule_engine_with_output_parameter_workflow_it_evaluate_output()
+ {
+ //Arrange
+ var workflowProvider = Substitute.For();
+ var workflows = CreateFakeWorkflowsWithOutput();
+ workflowProvider.GetAllWorkflows().Returns(workflows);
+
+ var stepActionFactory = Substitute.For();
+ var stepExecutionEvaluator = Substitute.For();
+ var actionFlowEngine = new ActionFlowEngine(workflowProvider, stepActionFactory, stepExecutionEvaluator);
+
+ var executionContext = new ExecutionContext(actionFlowEngine);
+ executionContext.AddOrUpdateParameter(new Parameter { Name = "age", Expression = "1" });
+ executionContext.AddOrUpdateParameter(new Parameter { Name = "canWalk", Expression = "true" });
+
+ stepExecutionEvaluator.EvaluateAndRunStep(workflows[0].Steps[0], executionContext, stepActionFactory).ReturnsForAnyArgs(executionContext);
+
+ //Act
+ var output = await actionFlowEngine.ExecuteWorkflowAsync("Test Workflow Rule 1", executionContext);
+
+ //Assert
+ await stepExecutionEvaluator.ReceivedWithAnyArgs(1).EvaluateAndRunStep(workflows[0].Steps[0], new ExecutionContext(actionFlowEngine), stepActionFactory);
+ Assert.AreEqual(2 ,output.OutputParameters.Count);
+ Assert.AreEqual(false, output.OutputParameters["canVote"]);
+ Assert.AreEqual(1, output.OutputParameters["age"]);
+ }
+
+ private static List CreateFakeWorkflows()
+ {
+ List workflows = [];
+ var steps = new List
+ {
+ new("initialize", "Variable", new Dictionary
+ {
+ { "age", "1" },
+ { "canWalk", "true" },
+ }),
+ new("test variable value", "Variable", [], "age == 1 && canWalk == true")
+ };
+
+ Workflow workflow = new Workflow("Test Workflow Rule 1", steps);
+ workflows.Add(workflow);
+
+ return workflows;
+ }
+
+ private static List CreateFakeWorkflowsWithOutput()
+ {
+ List workflows = [];
+ var steps = new List
+ {
+ new("test variable value", "Variable", [], "age == 1 && canWalk == true")
+ };
+
+ Workflow workflow = new Workflow("Test Workflow Rule 1", steps,
[
- new Parameter{ Name = "canVote", Expression = "age >= 18 && canWalk == true"},
- new Parameter{ Name = "age", Expression = "age"}
- ]);
- workflows.Add(workflow);
-
- return workflows;
- }
- }
+ new() { Name = "canVote", Expression = "age >= 18 && canWalk == true"},
+ new() { Name = "age", Expression = "age"}
+ ]);
+ workflows.Add(workflow);
+
+ return workflows;
+ }
+ }
}
diff --git a/ActionFlow.Tests/Extensions/ServiceCollectionExtensionsTests.cs b/ActionFlow.Tests/Extensions/ServiceCollectionExtensionsTests.cs
index 5538f9d..604dff3 100644
--- a/ActionFlow.Tests/Extensions/ServiceCollectionExtensionsTests.cs
+++ b/ActionFlow.Tests/Extensions/ServiceCollectionExtensionsTests.cs
@@ -23,10 +23,10 @@ public void When_using_action_flow_engine_it_should_register_all_required_servic
//Assert
Assert.IsNotNull(provider.GetRequiredService());
- Assert.IsNotNull(provider.GetRequiredService());
Assert.IsNotNull(provider.GetRequiredService());
Assert.IsNotNull(provider.GetRequiredService());
Assert.IsNotNull(provider.GetRequiredService());
+ Assert.IsNotNull(provider.GetRequiredService());
Assert.IsNotNull(provider.GetRequiredService>());
var stepActionFactory = provider.GetRequiredService();
diff --git a/ActionFlow.Tests/Providers/WorkflowProviderBuiltinExtensionsTests.cs b/ActionFlow.Tests/Providers/WorkflowProviderBuiltinExtensionsTests.cs
new file mode 100644
index 0000000..0ac97d3
--- /dev/null
+++ b/ActionFlow.Tests/Providers/WorkflowProviderBuiltinExtensionsTests.cs
@@ -0,0 +1,72 @@
+using ActionFlow.Domain.Engine;
+using ActionFlow.Engine.Providers;
+using ActionFlow.Engine.Providers.Extensions;
+using FluentAssertions;
+using Microsoft.Extensions.DependencyInjection;
+using System.Text.Json;
+
+namespace ActionFlow.Tests.Providers;
+
+[TestClass]
+public class WorkflowProviderBuiltinExtensionsTests
+{
+ [TestMethod]
+ public void When_using_from_json_it_should_add_workflow()
+ {
+ //Arrange
+ var workflows = new List
+ {
+ new("Test",
+ [
+ new("initialize", "Variable", new Dictionary
+ {
+ { "age", "1" },
+ { "canWalk", "true" },
+ }),
+ new("test variable value", "Variable", [], "age == 1 && canWalk == true")
+ ])
+ };
+
+ var workflowJson = JsonSerializer.SerializeToNode(workflows);
+ var services = new ServiceCollection();
+ services.AddJsonWorkflowProvider(workflowJson!.AsArray());
+
+ //Act
+ var provider = services.BuildServiceProvider();
+
+ //Assert
+ var workflowProvider = provider.GetRequiredService();
+ var result = workflowProvider.GetAllWorkflows();
+ result.Should().BeEquivalentTo(workflows);
+ }
+
+ [TestMethod]
+ public void When_using_from_json_file_it_should_add_workflow()
+ {
+ //Arrange
+ var expected = new List
+ {
+ new("Test",
+ [
+ new("initialize", "Variable", new Dictionary
+ {
+ { "age", "1" },
+ { "canWalk", "true" },
+ }),
+ new("test variable value", "Variable", [], "age == 1 && canWalk == true")
+ ])
+ };
+
+ var services = new ServiceCollection();
+ var path = Path.Combine(Environment.CurrentDirectory, @"Providers\workflows.json");
+ services.AddJsonWorkflowProvider(path);
+
+ //Act
+ var provider = services.BuildServiceProvider();
+
+ //Assert
+ var workflowProvider = provider.GetRequiredService();
+ var result = workflowProvider.GetAllWorkflows();
+ result.Should().BeEquivalentTo(expected);
+ }
+}
diff --git a/ActionFlow.Tests/Providers/WorkflowProviderTests.cs b/ActionFlow.Tests/Providers/WorkflowProviderTests.cs
new file mode 100644
index 0000000..d38b811
--- /dev/null
+++ b/ActionFlow.Tests/Providers/WorkflowProviderTests.cs
@@ -0,0 +1,26 @@
+using ActionFlow.Domain.Engine;
+using ActionFlow.Engine.Providers;
+
+namespace ActionFlow.Tests.Providers;
+
+[TestClass]
+public class WorkflowProviderTests
+{
+ [TestMethod]
+ public void When_getting_all_workflows_it_should_return_a_list()
+ {
+ //Arrange
+ var testWorkflows = new List
+ {
+ new("test", [])
+ };
+ var sut = new WorkflowProvider(testWorkflows);
+
+ //Act
+ var result = sut.GetAllWorkflows();
+
+ //Assert
+ Assert.IsInstanceOfType(result, typeof(List));
+ Assert.IsTrue(result.Contains(testWorkflows[0]));
+ }
+}
diff --git a/ActionFlow.Tests/Providers/workflows.json b/ActionFlow.Tests/Providers/workflows.json
new file mode 100644
index 0000000..30994cc
--- /dev/null
+++ b/ActionFlow.Tests/Providers/workflows.json
@@ -0,0 +1,23 @@
+[
+ {
+ "WorkflowName": "Test",
+ "Steps": [
+ {
+ "Name": "initialize",
+ "ActionType": "Variable",
+ "ConditionExpression": null,
+ "Properties": {
+ "age": "1",
+ "canWalk": "true"
+ }
+ },
+ {
+ "Name": "test variable value",
+ "ActionType": "Variable",
+ "ConditionExpression": "age == 1 \u0026\u0026 canWalk == true",
+ "Properties": {}
+ }
+ ],
+ "OutputParameters": null
+ }
+]
\ No newline at end of file
diff --git a/ActionFlow/Domain/Actions/ApiCallResult.cs b/ActionFlow/Domain/Actions/ApiCallResult.cs
index d4eac6c..44a894f 100644
--- a/ActionFlow/Domain/Actions/ApiCallResult.cs
+++ b/ActionFlow/Domain/Actions/ApiCallResult.cs
@@ -2,10 +2,17 @@
namespace ActionFlow.Domain.Actions
{
- public class ApiCallResult(JsonNode body, Dictionary> headers, int statusCode)
- {
- public JsonNode Body { get; } = body;
- public int StatusCode { get; } = statusCode;
- public Dictionary> Headers { get; } = headers;
- }
+ public class ApiCallResult
+ {
+ public ApiCallResult(JsonNode body, Dictionary> headers, int statusCode)
+ {
+ Body = body;
+ Headers = headers;
+ StatusCode = statusCode;
+ }
+
+ public JsonNode Body { get; }
+ public int StatusCode { get; }
+ public Dictionary> Headers { get; } = [];
+ }
}
diff --git a/ActionFlow/Domain/Engine/Step.cs b/ActionFlow/Domain/Engine/Step.cs
index e4576e0..047e747 100644
--- a/ActionFlow/Domain/Engine/Step.cs
+++ b/ActionFlow/Domain/Engine/Step.cs
@@ -1,10 +1,19 @@
namespace ActionFlow.Domain.Engine
{
- public class Step(string name, string actionType, Dictionary? properties = null, string? conditionExpression = null)
+ public class Step
{
- public string Name { get; } = name;
- public string ActionType { get; } = actionType;
- public string? ConditionExpression { get; } = conditionExpression;
- public Dictionary? Properties { get; } = properties ?? [];
+ public Step(string name, string actionType, Dictionary? properties = null, string? conditionExpression = null)
+ {
+ Name = name;
+ ActionType = actionType;
+ Properties = properties ?? [];
+ ConditionExpression = conditionExpression;
+ }
+
+ public string Name { get; }
+ public string ActionType { get; }
+ public string? ConditionExpression { get; }
+
+ public Dictionary? Properties { get; }
}
}
diff --git a/ActionFlow/Engine/ExecutionContext.cs b/ActionFlow/Engine/ExecutionContext.cs
index bfb4b6a..8c2b608 100644
--- a/ActionFlow/Engine/ExecutionContext.cs
+++ b/ActionFlow/Engine/ExecutionContext.cs
@@ -2,65 +2,72 @@
namespace ActionFlow.Engine
{
- public class ExecutionContext(IActionFlowEngine actionFlowEngine)
- {
- private readonly Interpreter _intepreter = new Interpreter();
- private readonly IActionFlowEngine _actionFlowEngine = actionFlowEngine;
+ public class ExecutionContext
+ {
+ private readonly Interpreter _intepreter;
+ private readonly IActionFlowEngine _actionFlowEngine;
- private Dictionary _actionProperties { get; } = [];
+ public ExecutionContext(IActionFlowEngine actionFlowEngine)
+ {
+ _actionProperties = [];
+ _intepreter = new Interpreter();
+ _actionFlowEngine = actionFlowEngine;
+ }
- public IActionFlowEngine GetCurrentEngine() => _actionFlowEngine;
+ private Dictionary _actionProperties { get; }
- public void AddOrUpdateParameter(Domain.Engine.Parameter parameter)
- {
- AddOrUpdateParameter(parameter.Name!, _intepreter.Eval(parameter.Expression));
- }
+ public IActionFlowEngine GetCurrentEngine() => _actionFlowEngine;
- public void AddOrUpdateParameter(string name, object value)
- {
- _intepreter.SetVariable(name, value);
- }
+ public void AddOrUpdateParameter(Domain.Engine.Parameter parameter)
+ {
+ AddOrUpdateParameter(parameter.Name!, _intepreter.Eval(parameter.Expression));
+ }
- public T GetParameter(string key)
- {
- return _intepreter.Eval(key);
- }
+ public void AddOrUpdateParameter(string name, object value)
+ {
+ _intepreter.SetVariable(name, value);
+ }
- public T EvaluateExpression(string expression)
- {
- return _intepreter.Eval(expression);
- }
+ public T GetParameter(string key)
+ {
+ return _intepreter.Eval(key);
+ }
- public void AddOrUpdateActionProperty(string key, object value)
- {
- if (_actionProperties.ContainsKey(key))
- {
- _actionProperties[key] = value;
- }
- else
- {
- _actionProperties.Add(key, value);
- }
- }
+ public T EvaluateExpression(string expression)
+ {
+ return _intepreter.Eval(expression);
+ }
- public T? GetActionProperty(string key)
- {
- if (_actionProperties.TryGetValue(key, out var value))
- {
- return (T)value;
- }
+ public void AddOrUpdateActionProperty(string key, object value)
+ {
+ if (_actionProperties.ContainsKey(key))
+ {
+ _actionProperties[key] = value;
+ }
+ else
+ {
+ _actionProperties.Add(key, value);
+ }
+ }
- return default;
- }
+ public T? GetActionProperty(string key)
+ {
+ if (_actionProperties.TryGetValue(key, out var value))
+ {
+ return (T)value;
+ }
- public void ClearActionProperties()
- {
- foreach (var propertyKey in _actionProperties.Keys)
- {
- _intepreter.UnsetVariable(propertyKey);
- }
+ return default;
+ }
- _actionProperties.Clear();
- }
- }
+ public void ClearActionProperties()
+ {
+ foreach (var propertyKey in _actionProperties.Keys)
+ {
+ _intepreter.UnsetVariable(propertyKey);
+ }
+
+ _actionProperties.Clear();
+ }
+ }
}
diff --git a/ActionFlow/Engine/Providers/Extensions/WorkflowProviderBuiltinExtensions.cs b/ActionFlow/Engine/Providers/Extensions/WorkflowProviderBuiltinExtensions.cs
new file mode 100644
index 0000000..22f9dc2
--- /dev/null
+++ b/ActionFlow/Engine/Providers/Extensions/WorkflowProviderBuiltinExtensions.cs
@@ -0,0 +1,59 @@
+using ActionFlow.Domain.Engine;
+using Microsoft.Extensions.DependencyInjection;
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using System.Text.Json.Serialization;
+
+namespace ActionFlow.Engine.Providers.Extensions;
+public static class WorkflowProviderBuiltinExtensions
+{
+ public static void AddJsonWorkflowProvider(this IServiceCollection services, string jsonPath)
+ {
+ var jsonString = File.ReadAllText(jsonPath);
+ var workflowsJson = JsonArray.Parse(jsonString)?.AsArray();
+
+ services.AddJsonWorkflowProvider(workflowsJson!);
+ }
+
+ public static void AddJsonWorkflowProvider(this IServiceCollection services, JsonArray workflowsJson)
+ {
+ var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
+ options.Converters.Add(new ObjectToStringConverter());
+
+ var workflows = workflowsJson.Deserialize>(options);
+
+ if (workflows != null)
+ {
+ services.AddScoped(x =>
+ {
+ return new WorkflowProvider([.. workflows]);
+ });
+ }
+ }
+
+ public class ObjectToStringConverter : JsonConverter