-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6f2c3c7
commit 8c3564f
Showing
12 changed files
with
356 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
using ActionFlow.Engine; | ||
using ActionFlow.Rules; | ||
using NSubstitute; | ||
using RulesEngine.Models; | ||
|
||
namespace ActionFlow.Tests.Rules | ||
{ | ||
[TestClass] | ||
public class ApiCallRuleTests | ||
{ | ||
[TestMethod] | ||
public void When_running_api_call_rule_with_get_method_it_should_execute() | ||
{ | ||
//Arrange | ||
var workflowProvider = Substitute.For<IWorkflowProvider>(); | ||
workflowProvider.GetAllWorkflows().Returns(CreateGetApiCallRuleWorkflow()); | ||
|
||
var rulesEngine = new RuleEngineWrapper(workflowProvider, new ReSettingsProvider()); | ||
|
||
//Act | ||
var resultList = rulesEngine.ExecuteAllRulesAsync("Test Workflow Rule 1", new object[] { }).Result; | ||
|
||
//Assert | ||
Assert.IsTrue(resultList.TrueForAll(x => x.IsSuccess)); | ||
} | ||
|
||
[TestMethod] | ||
public void When_running_api_call_rule_with_post_method_it_should_execute() | ||
{ | ||
//Arrange | ||
var workflowProvider = Substitute.For<IWorkflowProvider>(); | ||
workflowProvider.GetAllWorkflows().Returns(CreatePostApiCallRuleWorkflow()); | ||
|
||
var rulesEngine = new RuleEngineWrapper(workflowProvider, new ReSettingsProvider()); | ||
|
||
//Act | ||
var resultList = rulesEngine.ExecuteAllRulesAsync("Test Workflow Rule 1", new object[] { }).Result; | ||
|
||
//Assert | ||
Assert.IsTrue(resultList.TrueForAll(x => x.IsSuccess)); | ||
} | ||
|
||
[TestMethod] | ||
public void When_running_api_call_rule_with_headers_it_should_execute_and_return_200_status_code() | ||
{ | ||
//Arrange | ||
var workflowProvider = Substitute.For<IWorkflowProvider>(); | ||
workflowProvider.GetAllWorkflows().Returns(CreateApiCallRuleWithHeadersWorkflow()); | ||
|
||
var rulesEngine = new RuleEngineWrapper(workflowProvider, new ReSettingsProvider()); | ||
|
||
//Act | ||
var resultList = rulesEngine.ExecuteAllRulesAsync("Test Workflow Rule 1", new object[] { }).Result; | ||
|
||
//Assert | ||
Assert.IsTrue(resultList.TrueForAll(x => x.IsSuccess)); | ||
} | ||
|
||
private List<Workflow> CreateGetApiCallRuleWorkflow() | ||
{ | ||
List<Workflow> workflows = new List<Workflow>(); | ||
Workflow workflow = new Workflow(); | ||
workflow.WorkflowName = "Test Workflow Rule 1"; | ||
|
||
List<Rule> rules = new List<Rule>(); | ||
|
||
var apiCallRule = new ApiCallRule(); | ||
apiCallRule.Name = "Call test api"; | ||
apiCallRule.Url = "http://httpbin.org/get"; | ||
apiCallRule.ReturnVariableName = "apiResult"; | ||
|
||
var variableRule2 = new VariableRule(); | ||
variableRule2.Name = "Test api call result"; | ||
variableRule2.ConditionExpression = "apiResult.Body != null"; | ||
|
||
apiCallRule.Rules.Add(variableRule2); | ||
|
||
rules.Add(apiCallRule.AsRuleEngineRule()); | ||
workflow.Rules = rules; | ||
workflows.Add(workflow); | ||
|
||
return workflows; | ||
} | ||
|
||
private List<Workflow> CreateApiCallRuleWithHeadersWorkflow() | ||
{ | ||
List<Workflow> workflows = new List<Workflow>(); | ||
Workflow workflow = new Workflow(); | ||
workflow.WorkflowName = "Test Workflow Rule 1"; | ||
|
||
List<Rule> rules = new List<Rule>(); | ||
|
||
var apiCallRule = new ApiCallRule(); | ||
apiCallRule.Name = "Call test api"; | ||
apiCallRule.Url = "http://httpbin.org/get"; | ||
apiCallRule.Headers = new Dictionary<string, string> | ||
{ | ||
{ "test", "value" } | ||
}; | ||
apiCallRule.ReturnVariableName = "apiResult"; | ||
|
||
var variableRule2 = new VariableRule(); | ||
variableRule2.Name = "Test api call result"; | ||
variableRule2.ConditionExpression = "apiResult.StatusCode == 200"; | ||
|
||
apiCallRule.Rules.Add(variableRule2); | ||
|
||
rules.Add(apiCallRule.AsRuleEngineRule()); | ||
workflow.Rules = rules; | ||
workflows.Add(workflow); | ||
|
||
return workflows; | ||
} | ||
|
||
private List<Workflow> CreatePostApiCallRuleWorkflow() | ||
{ | ||
List<Workflow> workflows = new List<Workflow>(); | ||
Workflow workflow = new Workflow(); | ||
workflow.WorkflowName = "Test Workflow Rule 1"; | ||
|
||
List<Rule> rules = new List<Rule>(); | ||
|
||
var apiCallRule = new ApiCallRule(); | ||
apiCallRule.Name = "Call test api"; | ||
apiCallRule.Method = "POST"; | ||
apiCallRule.Url = "http://httpbin.org/post"; | ||
apiCallRule.ReturnVariableName = "apiResult"; | ||
|
||
string jsonString = "{ \"test\": true }"; | ||
apiCallRule.Content = jsonString; | ||
|
||
var variableRule2 = new VariableRule(); | ||
variableRule2.Name = "Test api call result"; | ||
variableRule2.Variables = new Dictionary<string, string> | ||
{ | ||
{ "apiBodyJson", "bool.Parse(apiResult.Body.json.test.ToString())" } | ||
}; | ||
variableRule2.ConditionExpression = "apiResult.Body.json != null"; | ||
|
||
var variableRule3 = new VariableRule(); | ||
variableRule3.Name = "Test apiBodyJson"; | ||
variableRule3.ConditionExpression = "apiBodyJson == \"true\""; | ||
|
||
variableRule2.Rules.Add(variableRule3); | ||
apiCallRule.Rules.Add(variableRule2); | ||
|
||
rules.Add(apiCallRule.AsRuleEngineRule()); | ||
workflow.Rules = rules; | ||
workflows.Add(workflow); | ||
|
||
return workflows; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
using System.Text.Json.Nodes; | ||
|
||
namespace ActionFlow.Domain | ||
{ | ||
public class ApiCallResult | ||
{ | ||
public ApiCallResult(JsonNode body, Dictionary<string, IEnumerable<string>> headers, int statusCode) | ||
{ | ||
Body = body; | ||
Headers = headers; | ||
StatusCode = statusCode; | ||
} | ||
|
||
public JsonNode Body { get; } | ||
public int StatusCode { get; } | ||
public Dictionary<string, IEnumerable<string>> Headers { get; } = new Dictionary<string, IEnumerable<string>>(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
using RulesEngine.Models; | ||
|
||
namespace ActionFlow.Engine | ||
{ | ||
public interface IReSettingsProvider | ||
{ | ||
ReSettings GetReSettings(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
using ActionFlow.Domain; | ||
using ActionFlow.Helpers; | ||
using RulesEngine.Models; | ||
|
||
namespace ActionFlow.Engine | ||
{ | ||
public class ReSettingsProvider : IReSettingsProvider | ||
{ | ||
public ReSettings GetReSettings() | ||
{ | ||
var reSettingsWithCustomTypes = new ReSettings | ||
{ | ||
CustomTypes = new Type[] { typeof(ApiClient), typeof(ApiCallResult) } | ||
}; | ||
|
||
return reSettingsWithCustomTypes; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
using ActionFlow.Domain; | ||
using Newtonsoft.Json; | ||
using System.Text.Json.Nodes; | ||
|
||
namespace ActionFlow.Helpers | ||
{ | ||
public static class ApiClient | ||
{ | ||
public static async Task<ApiCallResult> CallGet(string url, string? requestHeaders = null) | ||
{ | ||
var httpClient = new HttpClient(); | ||
AddRequestHeaders(requestHeaders, httpClient); | ||
|
||
var result = await httpClient.GetAsync(url); | ||
return await CreateApiCallResult(result); | ||
} | ||
|
||
public static async Task<ApiCallResult> CallPost(string url, string data, string? requestHeaders = null) | ||
{ | ||
var httpClient = new HttpClient(); | ||
AddRequestHeaders(requestHeaders, httpClient); | ||
|
||
var json = JsonNode.Parse(data); | ||
var content = new StringContent(json!.ToJsonString()); | ||
var result = await httpClient.PostAsync(url, content); | ||
|
||
return await CreateApiCallResult(result); | ||
} | ||
|
||
private static void AddRequestHeaders(string? requestHeaders, HttpClient httpClient) | ||
{ | ||
if (requestHeaders != null) | ||
{ | ||
var headerDictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(requestHeaders); | ||
foreach (var header in headerDictionary!) | ||
{ | ||
httpClient.DefaultRequestHeaders.Add(header.Key, header.Value); | ||
} | ||
} | ||
} | ||
|
||
private static async Task<ApiCallResult> CreateApiCallResult(HttpResponseMessage result) | ||
{ | ||
var jsonBody = JsonNode.Parse(await result.Content.ReadAsStringAsync()); | ||
var headers = result.Headers.ToDictionary(x => x.Key, x => x.Value); | ||
var statusCode = (int)result.StatusCode; | ||
|
||
var apiCallResult = new ApiCallResult(jsonBody!, headers, statusCode); | ||
return apiCallResult; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
using Newtonsoft.Json; | ||
using RulesEngine.Models; | ||
|
||
namespace ActionFlow.Rules | ||
{ | ||
public class ApiCallRule : RuleWrapper | ||
{ | ||
public override string RuleType => "ApiCall"; | ||
public string? Url { get; set; } | ||
public string Method { get; set; } = "GET"; | ||
public Dictionary<string, string> Headers { get; set; } = new Dictionary<string, string>(); | ||
public string? ReturnVariableName { get; set; } | ||
public string? Content { get; set; } | ||
|
||
public override Rule AsRuleEngineRule() | ||
{ | ||
var rule = base.AsRuleEngineRule(); | ||
var serializedHeaders = JsonConvert.SerializeObject(JsonConvert.SerializeObject(Headers)); | ||
//JsonConvert.SerializeObject(Headers); | ||
|
||
switch (Method) | ||
{ | ||
case "GET": | ||
rule.LocalParams = new List<ScopedParam> | ||
{ | ||
{ new ScopedParam { Name = ReturnVariableName!, Expression = $"ApiClient.CallGet(\"{Url}\", {serializedHeaders}).Result" } } | ||
}; | ||
break; | ||
|
||
case "POST": | ||
var content = JsonConvert.SerializeObject(Content); | ||
|
||
rule.LocalParams = new List<ScopedParam> | ||
{ | ||
{ new ScopedParam { Name = ReturnVariableName!, Expression = $"ApiClient.CallPost(\"{Url}\", {content}, {serializedHeaders}).Result" } } | ||
}; | ||
break; | ||
} | ||
|
||
|
||
return rule; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.