Skip to content

Commit

Permalink
fix unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
jakemoresca committed Jul 11, 2024
1 parent 41bc78a commit 79e6f04
Show file tree
Hide file tree
Showing 10 changed files with 201 additions and 46 deletions.
7 changes: 7 additions & 0 deletions ActionFlow.Tests/ActionFlow.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

<ItemGroup>
<PackageReference Include="DynamicExpresso.Core" Version="2.16.1" />
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.4.3" />
<PackageReference Include="MSTest.TestFramework" Version="3.4.3" />
Expand All @@ -24,4 +25,10 @@
<ProjectReference Include="..\ActionFlow\ActionFlow.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="Providers\workflows.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ public void When_using_action_flow_engine_it_should_register_all_required_servic

//Assert
Assert.IsNotNull(provider.GetRequiredService<IActionFlowEngine>());
Assert.IsNotNull(provider.GetRequiredService<IWorkflowProvider>());
Assert.IsNotNull(provider.GetRequiredService<IStepExecutionEvaluator>());
Assert.IsNotNull(provider.GetRequiredService<IStepActionFactory>());
Assert.IsNotNull(provider.GetRequiredService<IApiClient>());
Assert.IsNotNull(provider.GetRequiredService<IWorkflowProvider>());
Assert.IsNotNull(provider.GetRequiredService<IEnumerable<IActionBase>>());

var stepActionFactory = provider.GetRequiredService<IStepActionFactory>();
Expand Down
Original file line number Diff line number Diff line change
@@ -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<Workflow>
{
new("Test",
[
new("initialize", "Variable", new Dictionary<string, object>
{
{ "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<IWorkflowProvider>();
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<Workflow>
{
new("Test",
[
new("initialize", "Variable", new Dictionary<string, object>
{
{ "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<IWorkflowProvider>();
var result = workflowProvider.GetAllWorkflows();
result.Should().BeEquivalentTo(expected);
}
}
26 changes: 26 additions & 0 deletions ActionFlow.Tests/Providers/WorkflowProviderTests.cs
Original file line number Diff line number Diff line change
@@ -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<Workflow>
{
new("test", [])
};
var sut = new WorkflowProvider(testWorkflows);

//Act
var result = sut.GetAllWorkflows();

//Assert
Assert.IsInstanceOfType(result, typeof(List<Workflow>));
Assert.IsTrue(result.Contains(testWorkflows[0]));
}
}
23 changes: 23 additions & 0 deletions ActionFlow.Tests/Providers/workflows.json
Original file line number Diff line number Diff line change
@@ -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
}
]
29 changes: 15 additions & 14 deletions ActionFlow/Domain/Engine/Step.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
namespace ActionFlow.Domain.Engine
{
public class Step
{
public Step(string name, string actionType, Dictionary<string, object>? properties = null, string? conditionExpression = null)
{
Name = name;
ActionType = actionType;
Properties = properties ?? [];
ConditionExpression = conditionExpression;
}
public class Step
{
public Step(string name, string actionType, Dictionary<string, object>? 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<string, object>? Properties { get; }
}
public string Name { get; }
public string ActionType { get; }
public string? ConditionExpression { get; }

public Dictionary<string, object>? Properties { get; }
}
}
Original file line number Diff line number Diff line change
@@ -1,28 +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 UseFromJson(this IWorkflowProvider workflowProvider, JsonArray workflowsJson)
public static void AddJsonWorkflowProvider(this IServiceCollection services, string jsonPath)
{
var workflows = workflowsJson.Deserialize<Workflow[]>();
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<List<Workflow>>(options);

if (workflows != null)
{
foreach (var workflow in workflows)
services.AddScoped<IWorkflowProvider>(x =>
{
workflowProvider.AddWorkflow(workflow);
}
return new WorkflowProvider([.. workflows]);
});
}
}

public static void UseFromJson(this IWorkflowProvider workflowProvider, string jsonPath)
public class ObjectToStringConverter : JsonConverter<object>
{
var jsonBytes = File.ReadAllBytes(jsonPath);
var workflowsJson = JsonArray.Parse(jsonBytes)?.AsArray();
public override bool CanConvert(Type typeToConvert) => typeof(object) == typeToConvert;

workflowProvider.UseFromJson(workflowsJson!);
public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Number)
{
return reader.TryGetInt64(out long l) ? l.ToString() : reader.GetDouble().ToString();
}
if (reader.TokenType == JsonTokenType.String)
{
return reader.GetString();
}
using (JsonDocument document = JsonDocument.ParseValue(ref reader))
{
return document.RootElement.Clone().ToString();
}
}

public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
}
}
}
1 change: 0 additions & 1 deletion ActionFlow/Engine/Providers/IWorkflowProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@ namespace ActionFlow.Engine.Providers
public interface IWorkflowProvider
{
List<Workflow> GetAllWorkflows();
void AddWorkflow(Workflow workflow);
}
}
36 changes: 16 additions & 20 deletions ActionFlow/Engine/Providers/WorkflowProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,30 @@

namespace ActionFlow.Engine.Providers
{
public class WorkflowProvider : IWorkflowProvider
public class BlankWorkflowProvider() : WorkflowProvider(new List<Workflow>())
{
protected List<Workflow> _workflows = [];

public void AddWorkflow(Workflow workflow)
{
_workflows.Add(workflow);
}
}

public class WorkflowProvider(List<Workflow> workflows) : IWorkflowProvider
{
public List<Workflow> GetAllWorkflows()
{
List<Workflow> workflows = [];

//Test
//Todo: Load from DB, Json, or other source
var steps = new List<Step>
{
new("initialize", "Variable", new Dictionary<string, object>
{
{ "age", "1" },
{ "canWalk", "true" },
}),
new("test variable value", "Variable", [], "age == 1 && canWalk == true")
};
//var steps = new List<Step>
//{
// new("initialize", "Variable", new Dictionary<string, object>
// {
// { "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);
//Test End
//Workflow workflow = new Workflow("Test Workflow Rule 1", steps);
//workflows.Add(workflow);
////Test End

return workflows;
}
Expand Down
2 changes: 1 addition & 1 deletion ActionFlow/Extensions/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public static void AddDefaultActions(this IServiceCollection services)
public static void UseActionFlowEngine(this IServiceCollection services)
{
services.AddScoped<IActionFlowEngine, ActionFlowEngine>();
services.AddScoped<IWorkflowProvider, WorkflowProvider>();
services.AddScoped<IWorkflowProvider, BlankWorkflowProvider>();
services.AddScoped<IStepExecutionEvaluator, StepExecutionEvaluator>();
services.AddScoped<IStepActionFactory, StepActionFactory>();
services.AddScoped<IApiClient, ApiClient>();
Expand Down

0 comments on commit 79e6f04

Please sign in to comment.