From 86fd396e7e4571a2c240d9e11ca02bbff433c3eb Mon Sep 17 00:00:00 2001 From: "dante.barbosa" Date: Mon, 22 Apr 2024 11:19:48 -0300 Subject: [PATCH 01/13] #630626 - Adding Handlebars lib in Blip.Builder.csproj --- src/Take.Blip.Builder/Take.Blip.Builder.csproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Take.Blip.Builder/Take.Blip.Builder.csproj b/src/Take.Blip.Builder/Take.Blip.Builder.csproj index 73e5c64b..69ec76ad 100644 --- a/src/Take.Blip.Builder/Take.Blip.Builder.csproj +++ b/src/Take.Blip.Builder/Take.Blip.Builder.csproj @@ -8,12 +8,14 @@ + + From 0e7495a887b050f589f697bf189934c2ef6d8222 Mon Sep 17 00:00:00 2001 From: "dante.barbosa" Date: Mon, 22 Apr 2024 11:20:27 -0300 Subject: [PATCH 02/13] #630626 - Creating Action and Settings --- .../ExecuteTemplate/ExecuteTemplateAction.cs | 66 +++++++++++++++++++ .../ExecuteTemplateSettings.cs | 22 +++++++ 2 files changed, 88 insertions(+) create mode 100644 src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs create mode 100644 src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateSettings.cs diff --git a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs new file mode 100644 index 00000000..1237f92a --- /dev/null +++ b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs @@ -0,0 +1,66 @@ +using System.Threading; +using System.Threading.Tasks; +using HandlebarsDotNet; +using HandlebarsDotNet.Extension.Json; +using Newtonsoft.Json.Linq; +using Serilog; +using Take.Blip.Builder.Hosting; + +namespace Take.Blip.Builder.Actions.ExecuteTemplate +{ + public class ExecuteTemplateAction : ActionBase + { + private readonly IConfiguration _configuration; + private readonly ILogger _logger; + private readonly IHandlebars _handlebars; + + public ExecuteTemplateAction(IConfiguration configuration, ILogger logger) : base(nameof(ExecuteTemplateAction)) + { + configuration = _configuration; + logger = _logger; + _handlebars = Handlebars.Create(); + _handlebars.Configuration.UseJson(); + } + + public override async Task ExecuteAsync(IContext context, ExecuteTemplateSettings settings, CancellationToken cancellationToken) + { + var jObject = await GetScriptArgumentsAsync(context, settings, cancellationToken); + var template = _handlebars.Compile(settings.Template); + if (template == null) + { + return; + } + var result = template(jObject); + await SetScriptResultAsync(context, settings, result, cancellationToken); + } + + private async Task GetScriptArgumentsAsync( + IContext context, ExecuteTemplateSettings settings, CancellationToken cancellationToken) + { + var obj = new JObject(); + if (settings.InputVariables != null && settings.InputVariables.Length > 0) + { + for (int i = 0; i < settings.InputVariables.Length; i++) + { + var variableValue = await context.GetVariableAsync(settings.InputVariables[i], cancellationToken); + obj[settings.InputVariables[i]] = variableValue; + + } + } + return obj; + } + + private async Task SetScriptResultAsync( + IContext context, ExecuteTemplateSettings settings, string result, CancellationToken cancellationToken) + { + if (!string.IsNullOrEmpty(result)) + { + await context.SetVariableAsync(settings.OutputVariable, result, cancellationToken); + } + else + { + await context.DeleteVariableAsync(settings.OutputVariable, cancellationToken); + } + } + } +} \ No newline at end of file diff --git a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateSettings.cs b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateSettings.cs new file mode 100644 index 00000000..655fd53e --- /dev/null +++ b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateSettings.cs @@ -0,0 +1,22 @@ +using System.ComponentModel.DataAnnotations; +using Take.Blip.Builder.Models; + +namespace Take.Blip.Builder.Actions.ExecuteTemplate +{ + public class ExecuteTemplateSettings : IValidable + { + public string[] InputVariables { get; set; } + + public string OutputVariable { get; set; } + + public string Template { get; set; } + + public void Validate() + { + if (string.IsNullOrEmpty(OutputVariable)) + { + throw new ValidationException($"The '{nameof(OutputVariable)}' settings value is required for '{nameof(ExecuteTemplateSettings)}' action"); + } + } + } +} \ No newline at end of file From eade9eb7f75e34026c2d9052276415eb461ebd5c Mon Sep 17 00:00:00 2001 From: "dante.barbosa" Date: Mon, 22 Apr 2024 12:25:25 -0300 Subject: [PATCH 03/13] #630626 - Creating unit testes and adding dependency --- .../Actions/ExecuteTemplateActionTests.cs | 38 +++++++++++++++++++ .../ExecuteTemplate/ExecuteTemplateAction.cs | 23 ++++++++--- .../Hosting/ContainerExtensions.cs | 4 +- 3 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs diff --git a/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs b/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs new file mode 100644 index 00000000..a36948e5 --- /dev/null +++ b/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs @@ -0,0 +1,38 @@ +using System; +using System.Threading.Tasks; +using NSubstitute; +using Serilog; +using Take.Blip.Builder.Actions.ExecuteTemplate; +using Take.Blip.Builder.Hosting; +using Xunit; + +namespace Take.Blip.Builder.UnitTests.Actions +{ + public class ExecuteTemplateActionTests : ActionTestsBase + { + private ExecuteTemplateAction GetTarget() + { + return new ExecuteTemplateAction(new ConventionsConfiguration(), Substitute.For()); + } + + [Fact] + public async Task ExecuteTemplateShouldSuccess() + { + var variableName = "TestName"; + var outputVariable = ""; + Context.GetVariableAsync(nameof(variableName), CancellationToken).Returns(variableName); + var settings = new ExecuteTemplateSettings + { + InputVariables = new []{ nameof(variableName) }, + Template = $"Name: {{{{{nameof(variableName)}}}}}", + OutputVariable = outputVariable + }; + var action = GetTarget(); + await action.ExecuteAsync(Context, settings, CancellationToken); + + // Assert + await Context.Received(1).SetVariableAsync(Arg.Any(), Arg.Any(), CancellationToken, Arg.Any()); + await Context.Received(1).SetVariableAsync(outputVariable, $"Name: {variableName}", CancellationToken); + } + } +} \ No newline at end of file diff --git a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs index 1237f92a..acf24b2f 100644 --- a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs +++ b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs @@ -1,4 +1,5 @@ -using System.Threading; +using System; +using System.Threading; using System.Threading.Tasks; using HandlebarsDotNet; using HandlebarsDotNet.Extension.Json; @@ -23,14 +24,24 @@ public ExecuteTemplateAction(IConfiguration configuration, ILogger logger) : bas } public override async Task ExecuteAsync(IContext context, ExecuteTemplateSettings settings, CancellationToken cancellationToken) - { + { + string result; var jObject = await GetScriptArgumentsAsync(context, settings, cancellationToken); - var template = _handlebars.Compile(settings.Template); - if (template == null) + try + { + var template = _handlebars.Compile(settings.Template); + if (template == null) + { + return; + } + result = template(jObject); + } + catch (Exception ex) { - return; + _logger.Error(ex, "Unexpected error while trying to execute Handlebars template"); + throw; } - var result = template(jObject); + await SetScriptResultAsync(context, settings, result, cancellationToken); } diff --git a/src/Take.Blip.Builder/Hosting/ContainerExtensions.cs b/src/Take.Blip.Builder/Hosting/ContainerExtensions.cs index 17d401b1..41bae3fc 100644 --- a/src/Take.Blip.Builder/Hosting/ContainerExtensions.cs +++ b/src/Take.Blip.Builder/Hosting/ContainerExtensions.cs @@ -7,6 +7,7 @@ using Take.Blip.Builder.Actions.CreateTicket; using Take.Blip.Builder.Actions.DeleteVariable; using Take.Blip.Builder.Actions.ExecuteScript; +using Take.Blip.Builder.Actions.ExecuteTemplate; using Take.Blip.Builder.Actions.ManageList; using Take.Blip.Builder.Actions.MergeContact; using Take.Blip.Builder.Actions.ProcessCommand; @@ -95,7 +96,8 @@ private static Container RegisterBuilderActions(this Container container) typeof(CreateTicketAction), typeof(DeleteVariableAction), typeof(ProcessContentAssistantAction), - typeof(TrackContactsJourneyAction) + typeof(TrackContactsJourneyAction), + typeof(ExecuteTemplateAction) }); return container; From c3ebc4435c7c65b913d7dee7db0d26653681ba74 Mon Sep 17 00:00:00 2001 From: "dante.barbosa" Date: Tue, 23 Apr 2024 10:12:55 -0300 Subject: [PATCH 04/13] #630626 - Creating tests, and fixing flow --- .../Actions/ExecuteTemplateActionTests.cs | 83 ++++++++++++++++++- .../ExecuteTemplate/ExecuteTemplateAction.cs | 38 +++++++-- .../ExecuteTemplateSettings.cs | 18 ++++ 3 files changed, 130 insertions(+), 9 deletions(-) diff --git a/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs b/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs index a36948e5..3036d543 100644 --- a/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs +++ b/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs @@ -1,10 +1,12 @@ using System; using System.Threading.Tasks; +using HandlebarsDotNet; using NSubstitute; using Serilog; using Take.Blip.Builder.Actions.ExecuteTemplate; using Take.Blip.Builder.Hosting; using Xunit; +using Shouldly; namespace Take.Blip.Builder.UnitTests.Actions { @@ -18,6 +20,7 @@ private ExecuteTemplateAction GetTarget() [Fact] public async Task ExecuteTemplateShouldSuccess() { + //Arrange var variableName = "TestName"; var outputVariable = ""; Context.GetVariableAsync(nameof(variableName), CancellationToken).Returns(variableName); @@ -25,8 +28,11 @@ public async Task ExecuteTemplateShouldSuccess() { InputVariables = new []{ nameof(variableName) }, Template = $"Name: {{{{{nameof(variableName)}}}}}", - OutputVariable = outputVariable + OutputVariable = outputVariable, + Handlebars = Handlebars.Create() }; + + //Act var action = GetTarget(); await action.ExecuteAsync(Context, settings, CancellationToken); @@ -34,5 +40,80 @@ public async Task ExecuteTemplateShouldSuccess() await Context.Received(1).SetVariableAsync(Arg.Any(), Arg.Any(), CancellationToken, Arg.Any()); await Context.Received(1).SetVariableAsync(outputVariable, $"Name: {variableName}", CancellationToken); } + + [Fact] + public async Task ExecuteTemplateWithObjectAsPropertyShouldSuccess() + { + //Arrange + var variableName = "{ \"people\": [{\"name\": \"testName\", \"city\": \"Aracaju\"}] }"; + var outputVariable = ""; + Context.GetVariableAsync(nameof(variableName), CancellationToken).Returns(variableName); + var settings = new ExecuteTemplateSettings + { + InputVariables = new []{ nameof(variableName) }, + Template = "Names: {{#each people}}{{name}} living in {{city}}{{/each}}", + OutputVariable = outputVariable, + Handlebars = Handlebars.Create() + }; + + //Act + var action = GetTarget(); + await action.ExecuteAsync(Context, settings, CancellationToken); + + // Assert + await Context.Received(1).SetVariableAsync(Arg.Any(), Arg.Any(), CancellationToken, Arg.Any()); + await Context.Received(1).SetVariableAsync(outputVariable, "Names: testName living in Aracaju", CancellationToken); + } + + + [Fact] + public async Task ExecuteTemplateShouldReturnWithoutExecution() + { + //Arrange + var variableName = "TestName"; + var outputVariable = ""; + Context.GetVariableAsync(nameof(variableName), CancellationToken).Returns(variableName); + var settings = new ExecuteTemplateSettings + { + InputVariables = new []{ nameof(variableName) }, + Template = $"Name: {{{{{nameof(variableName)}}}}}", + OutputVariable = outputVariable, + }; + + //Act + var action = GetTarget(); + await action.ExecuteAsync(Context, settings, CancellationToken); + + // Assert + await Context.Received(0).SetVariableAsync(Arg.Any(), Arg.Any(), CancellationToken, Arg.Any()); + } + + [Fact] + public async Task ExecuteTemplateShouldFail() + { + //Arrange + var variableName = "TestName"; + var outputVariable = ""; + Context.GetVariableAsync(nameof(variableName), CancellationToken).Returns(variableName); + var settings = new ExecuteTemplateSettings + { + InputVariables = new []{ nameof(variableName) }, + Template = $"Name: {{{{nameof(variableName)}}}}", + OutputVariable = outputVariable, + Handlebars = Handlebars.Create() + }; + + //Act + var action = GetTarget(); + try + { + await action.ExecuteAsync(Context, settings, CancellationToken); + throw new Exception("The template was executed"); + } + catch (HandlebarsCompilerException ex) + { + ex.Message.ShouldContain("could not be converted to an expression"); + } + } } } \ No newline at end of file diff --git a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs index acf24b2f..15bf4711 100644 --- a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs +++ b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs @@ -17,24 +17,39 @@ public class ExecuteTemplateAction : ActionBase public ExecuteTemplateAction(IConfiguration configuration, ILogger logger) : base(nameof(ExecuteTemplateAction)) { - configuration = _configuration; - logger = _logger; - _handlebars = Handlebars.Create(); - _handlebars.Configuration.UseJson(); + _configuration = configuration; + _logger = logger; } public override async Task ExecuteAsync(IContext context, ExecuteTemplateSettings settings, CancellationToken cancellationToken) { string result; - var jObject = await GetScriptArgumentsAsync(context, settings, cancellationToken); + var obj = new JObject(); + var arguments = await GetScriptArgumentsAsync(context, settings, cancellationToken); try { - var template = _handlebars.Compile(settings.Template); - if (template == null) + if (settings?.Handlebars == null) { return; } - result = template(jObject); + foreach (var property in arguments.Properties()) + { + if (IsJsonFormat(property.Value.ToString())) + { + var data = JObject.Parse(property.Value.ToString()); + foreach (var item in data) + { + obj[item.Key] = item.Value; + } + } + else + { + obj = arguments; + } + } + settings.Handlebars.Configuration.UseJson(); + var template = settings.Handlebars.Compile(settings.Template); + result = template(obj); } catch (Exception ex) { @@ -73,5 +88,12 @@ private async Task SetScriptResultAsync( await context.DeleteVariableAsync(settings.OutputVariable, cancellationToken); } } + + private bool IsJsonFormat(string strInput) + { + strInput = strInput.Trim(); + return (strInput.StartsWith("{") && strInput.EndsWith("}")) || + (strInput.StartsWith("[") && strInput.EndsWith("]")); + } } } \ No newline at end of file diff --git a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateSettings.cs b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateSettings.cs index 655fd53e..165980ae 100644 --- a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateSettings.cs +++ b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateSettings.cs @@ -1,15 +1,33 @@ using System.ComponentModel.DataAnnotations; +using HandlebarsDotNet; using Take.Blip.Builder.Models; namespace Take.Blip.Builder.Actions.ExecuteTemplate { + /// + /// Settings to Execute Template Action + /// public class ExecuteTemplateSettings : IValidable { + /// + /// Input Variables + /// public string[] InputVariables { get; set; } + /// + /// Output Variable + /// public string OutputVariable { get; set; } + /// + /// Template that will be transformed + /// public string Template { get; set; } + + /// + /// Instance of Handlebars + /// + public IHandlebars Handlebars { get; set; } public void Validate() { From 3f335dea52247fcda7e9976a7ac33d66c98d9f98 Mon Sep 17 00:00:00 2001 From: "dante.barbosa" Date: Tue, 23 Apr 2024 10:35:46 -0300 Subject: [PATCH 05/13] #630626 - Improve json validation --- .../ExecuteTemplate/ExecuteTemplateAction.cs | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs index 15bf4711..af845cb8 100644 --- a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs +++ b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using HandlebarsDotNet; using HandlebarsDotNet.Extension.Json; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Serilog; using Take.Blip.Builder.Hosting; @@ -28,16 +29,16 @@ public override async Task ExecuteAsync(IContext context, ExecuteTemplateSetting var arguments = await GetScriptArgumentsAsync(context, settings, cancellationToken); try { - if (settings?.Handlebars == null) + if (settings.Handlebars == null) { return; } foreach (var property in arguments.Properties()) { - if (IsJsonFormat(property.Value.ToString())) + var success = TryParseJson(property.Value.ToString(), out var jObject); + if (success) { - var data = JObject.Parse(property.Value.ToString()); - foreach (var item in data) + foreach (var item in jObject) { obj[item.Key] = item.Value; } @@ -89,11 +90,16 @@ private async Task SetScriptResultAsync( } } - private bool IsJsonFormat(string strInput) + private bool TryParseJson(string json, out T result) { - strInput = strInput.Trim(); - return (strInput.StartsWith("{") && strInput.EndsWith("}")) || - (strInput.StartsWith("[") && strInput.EndsWith("]")); + bool success = true; + var settings = new JsonSerializerSettings + { + Error = (sender, args) => { success = false; args.ErrorContext.Handled = true; }, + MissingMemberHandling = MissingMemberHandling.Error + }; + result = JsonConvert.DeserializeObject(json, settings); + return success; } } } \ No newline at end of file From 825e8efceb2e78dabfe29d6c262645b6fe4ab720 Mon Sep 17 00:00:00 2001 From: "dante.barbosa" Date: Tue, 23 Apr 2024 11:26:03 -0300 Subject: [PATCH 06/13] 630626 - Adding a conditional in flow and improve methods --- .../Actions/ExecuteTemplateActionTests.cs | 34 +++++++++++++-- .../ExecuteTemplate/ExecuteTemplateAction.cs | 42 +++++++++++-------- 2 files changed, 55 insertions(+), 21 deletions(-) diff --git a/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs b/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs index 3036d543..e2c980b0 100644 --- a/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs +++ b/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs @@ -45,12 +45,12 @@ public async Task ExecuteTemplateShouldSuccess() public async Task ExecuteTemplateWithObjectAsPropertyShouldSuccess() { //Arrange - var variableName = "{ \"people\": [{\"name\": \"testName\", \"city\": \"Aracaju\"}] }"; + var variableObj = "{ \"people\": [{\"name\": \"TestName\", \"city\": \"Aracaju\"}] }"; var outputVariable = ""; - Context.GetVariableAsync(nameof(variableName), CancellationToken).Returns(variableName); + Context.GetVariableAsync(nameof(variableObj), CancellationToken).Returns(variableObj); var settings = new ExecuteTemplateSettings { - InputVariables = new []{ nameof(variableName) }, + InputVariables = new []{ nameof(variableObj) }, Template = "Names: {{#each people}}{{name}} living in {{city}}{{/each}}", OutputVariable = outputVariable, Handlebars = Handlebars.Create() @@ -62,7 +62,33 @@ public async Task ExecuteTemplateWithObjectAsPropertyShouldSuccess() // Assert await Context.Received(1).SetVariableAsync(Arg.Any(), Arg.Any(), CancellationToken, Arg.Any()); - await Context.Received(1).SetVariableAsync(outputVariable, "Names: testName living in Aracaju", CancellationToken); + await Context.Received(1).SetVariableAsync(outputVariable, "Names: TestName living in Aracaju", CancellationToken); + } + + [Fact] + public async Task ExecuteTemplateWithObjectAndStringVariablesAsPropertyShouldSuccess() + { + //Arrange + var variableName = "Peoples:"; + var variableObj = "{ \"people\": [{\"name\": \"Carlos\", \"city\": \"Aracaju\"}] }"; + var outputVariable = ""; + Context.GetVariableAsync(nameof(variableName), CancellationToken).Returns(variableName); + Context.GetVariableAsync(nameof(variableObj), CancellationToken).Returns(variableObj); + var settings = new ExecuteTemplateSettings + { + InputVariables = new []{ nameof(variableName), nameof(variableObj) }, + Template = $"{{{{{nameof(variableName)}}}}} {{{{#each people}}}}{{{{name}}}} living in {{{{city}}}}{{{{/each}}}}", + OutputVariable = outputVariable, + Handlebars = Handlebars.Create() + }; + + //Act + var action = GetTarget(); + await action.ExecuteAsync(Context, settings, CancellationToken); + + // Assert + await Context.Received(1).SetVariableAsync(Arg.Any(), Arg.Any(), CancellationToken, Arg.Any()); + await Context.Received(1).SetVariableAsync(outputVariable, "Peoples: Carlos living in Aracaju", CancellationToken); } diff --git a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs index af845cb8..34a6ef3b 100644 --- a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs +++ b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs @@ -25,7 +25,6 @@ public ExecuteTemplateAction(IConfiguration configuration, ILogger logger) : bas public override async Task ExecuteAsync(IContext context, ExecuteTemplateSettings settings, CancellationToken cancellationToken) { string result; - var obj = new JObject(); var arguments = await GetScriptArgumentsAsync(context, settings, cancellationToken); try { @@ -33,22 +32,9 @@ public override async Task ExecuteAsync(IContext context, ExecuteTemplateSetting { return; } - foreach (var property in arguments.Properties()) - { - var success = TryParseJson(property.Value.ToString(), out var jObject); - if (success) - { - foreach (var item in jObject) - { - obj[item.Key] = item.Value; - } - } - else - { - obj = arguments; - } - } - settings.Handlebars.Configuration.UseJson(); + + var obj = CopyProperties(arguments); + var template = settings.Handlebars.Compile(settings.Template); result = template(obj); } @@ -90,6 +76,28 @@ private async Task SetScriptResultAsync( } } + private JObject CopyProperties(JObject arguments) + { + var obj = new JObject(); + foreach (var property in arguments.Properties()) + { + var success = TryParseJson(property.Value.ToString(), out var jObject); + if (success) + { + foreach (var item in jObject) + { + obj[item.Key] = item.Value; + } + } + else + { + obj[property.Name] = property.Value; + } + } + + return obj; + } + private bool TryParseJson(string json, out T result) { bool success = true; From 21c13e34e532b4932cc2880dd93d85f495aab600 Mon Sep 17 00:00:00 2001 From: "dante.barbosa" Date: Tue, 23 Apr 2024 21:26:36 -0300 Subject: [PATCH 07/13] 630626 - Improve tests and settings --- .../Actions/ExecuteTemplateActionTests.cs | 51 ++++++------------- .../ExecuteTemplate/ExecuteTemplateAction.cs | 13 ++--- .../ExecuteTemplateSettings.cs | 5 -- 3 files changed, 20 insertions(+), 49 deletions(-) diff --git a/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs b/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs index e2c980b0..d415adc9 100644 --- a/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs +++ b/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using HandlebarsDotNet; using NSubstitute; +using NSubstitute.ExceptionExtensions; using Serilog; using Take.Blip.Builder.Actions.ExecuteTemplate; using Take.Blip.Builder.Hosting; @@ -12,9 +13,11 @@ namespace Take.Blip.Builder.UnitTests.Actions { public class ExecuteTemplateActionTests : ActionTestsBase { + private IHandlebars Handlebars = Substitute.For(); + private ExecuteTemplateAction GetTarget() { - return new ExecuteTemplateAction(new ConventionsConfiguration(), Substitute.For()); + return new ExecuteTemplateAction(Handlebars, new ConventionsConfiguration(), Substitute.For()); } [Fact] @@ -24,12 +27,12 @@ public async Task ExecuteTemplateShouldSuccess() var variableName = "TestName"; var outputVariable = ""; Context.GetVariableAsync(nameof(variableName), CancellationToken).Returns(variableName); + var settings = new ExecuteTemplateSettings { InputVariables = new []{ nameof(variableName) }, Template = $"Name: {{{{{nameof(variableName)}}}}}", - OutputVariable = outputVariable, - Handlebars = Handlebars.Create() + OutputVariable = outputVariable }; //Act @@ -37,8 +40,8 @@ public async Task ExecuteTemplateShouldSuccess() await action.ExecuteAsync(Context, settings, CancellationToken); // Assert + Handlebars.Received(1).Compile(settings.Template); await Context.Received(1).SetVariableAsync(Arg.Any(), Arg.Any(), CancellationToken, Arg.Any()); - await Context.Received(1).SetVariableAsync(outputVariable, $"Name: {variableName}", CancellationToken); } [Fact] @@ -52,8 +55,7 @@ public async Task ExecuteTemplateWithObjectAsPropertyShouldSuccess() { InputVariables = new []{ nameof(variableObj) }, Template = "Names: {{#each people}}{{name}} living in {{city}}{{/each}}", - OutputVariable = outputVariable, - Handlebars = Handlebars.Create() + OutputVariable = outputVariable }; //Act @@ -61,8 +63,8 @@ public async Task ExecuteTemplateWithObjectAsPropertyShouldSuccess() await action.ExecuteAsync(Context, settings, CancellationToken); // Assert + Handlebars.Received(1).Compile(settings.Template); await Context.Received(1).SetVariableAsync(Arg.Any(), Arg.Any(), CancellationToken, Arg.Any()); - await Context.Received(1).SetVariableAsync(outputVariable, "Names: TestName living in Aracaju", CancellationToken); } [Fact] @@ -78,8 +80,7 @@ public async Task ExecuteTemplateWithObjectAndStringVariablesAsPropertyShouldSuc { InputVariables = new []{ nameof(variableName), nameof(variableObj) }, Template = $"{{{{{nameof(variableName)}}}}} {{{{#each people}}}}{{{{name}}}} living in {{{{city}}}}{{{{/each}}}}", - OutputVariable = outputVariable, - Handlebars = Handlebars.Create() + OutputVariable = outputVariable }; //Act @@ -87,31 +88,8 @@ public async Task ExecuteTemplateWithObjectAndStringVariablesAsPropertyShouldSuc await action.ExecuteAsync(Context, settings, CancellationToken); // Assert + Handlebars.Received(1).Compile(settings.Template); await Context.Received(1).SetVariableAsync(Arg.Any(), Arg.Any(), CancellationToken, Arg.Any()); - await Context.Received(1).SetVariableAsync(outputVariable, "Peoples: Carlos living in Aracaju", CancellationToken); - } - - - [Fact] - public async Task ExecuteTemplateShouldReturnWithoutExecution() - { - //Arrange - var variableName = "TestName"; - var outputVariable = ""; - Context.GetVariableAsync(nameof(variableName), CancellationToken).Returns(variableName); - var settings = new ExecuteTemplateSettings - { - InputVariables = new []{ nameof(variableName) }, - Template = $"Name: {{{{{nameof(variableName)}}}}}", - OutputVariable = outputVariable, - }; - - //Act - var action = GetTarget(); - await action.ExecuteAsync(Context, settings, CancellationToken); - - // Assert - await Context.Received(0).SetVariableAsync(Arg.Any(), Arg.Any(), CancellationToken, Arg.Any()); } [Fact] @@ -121,12 +99,12 @@ public async Task ExecuteTemplateShouldFail() var variableName = "TestName"; var outputVariable = ""; Context.GetVariableAsync(nameof(variableName), CancellationToken).Returns(variableName); + Handlebars.Compile("").ThrowsForAnyArgs(new HandlebarsCompilerException("could not be converted to an expression")); var settings = new ExecuteTemplateSettings { InputVariables = new []{ nameof(variableName) }, Template = $"Name: {{{{nameof(variableName)}}}}", - OutputVariable = outputVariable, - Handlebars = Handlebars.Create() + OutputVariable = outputVariable }; //Act @@ -140,6 +118,9 @@ public async Task ExecuteTemplateShouldFail() { ex.Message.ShouldContain("could not be converted to an expression"); } + + Handlebars.Received(1).Compile(settings.Template); + await Context.Received(0).SetVariableAsync(Arg.Any(), Arg.Any(), CancellationToken, Arg.Any()); } } } \ No newline at end of file diff --git a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs index 34a6ef3b..38634f66 100644 --- a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs +++ b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs @@ -16,10 +16,11 @@ public class ExecuteTemplateAction : ActionBase private readonly ILogger _logger; private readonly IHandlebars _handlebars; - public ExecuteTemplateAction(IConfiguration configuration, ILogger logger) : base(nameof(ExecuteTemplateAction)) + public ExecuteTemplateAction(IHandlebars handlebars, IConfiguration configuration, ILogger logger) : base(nameof(ExecuteTemplateAction)) { _configuration = configuration; _logger = logger; + _handlebars = handlebars; } public override async Task ExecuteAsync(IContext context, ExecuteTemplateSettings settings, CancellationToken cancellationToken) @@ -28,14 +29,8 @@ public override async Task ExecuteAsync(IContext context, ExecuteTemplateSetting var arguments = await GetScriptArgumentsAsync(context, settings, cancellationToken); try { - if (settings.Handlebars == null) - { - return; - } - var obj = CopyProperties(arguments); - - var template = settings.Handlebars.Compile(settings.Template); + var template = _handlebars.Compile(settings.Template); result = template(obj); } catch (Exception ex) @@ -66,7 +61,7 @@ private async Task GetScriptArgumentsAsync( private async Task SetScriptResultAsync( IContext context, ExecuteTemplateSettings settings, string result, CancellationToken cancellationToken) { - if (!string.IsNullOrEmpty(result)) + if (result != null) { await context.SetVariableAsync(settings.OutputVariable, result, cancellationToken); } diff --git a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateSettings.cs b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateSettings.cs index 165980ae..26074b7b 100644 --- a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateSettings.cs +++ b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateSettings.cs @@ -23,11 +23,6 @@ public class ExecuteTemplateSettings : IValidable /// Template that will be transformed /// public string Template { get; set; } - - /// - /// Instance of Handlebars - /// - public IHandlebars Handlebars { get; set; } public void Validate() { From 50268449897ab65b9eb5f783612b6e097ec5d8a8 Mon Sep 17 00:00:00 2001 From: "dante.barbosa" Date: Wed, 24 Apr 2024 10:01:30 -0300 Subject: [PATCH 08/13] 630626 - Improve method name --- .../Actions/ExecuteTemplate/ExecuteTemplateAction.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs index 38634f66..4af1db58 100644 --- a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs +++ b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs @@ -29,7 +29,7 @@ public override async Task ExecuteAsync(IContext context, ExecuteTemplateSetting var arguments = await GetScriptArgumentsAsync(context, settings, cancellationToken); try { - var obj = CopyProperties(arguments); + var obj = CopyPropertiesToObject(arguments); var template = _handlebars.Compile(settings.Template); result = template(obj); } @@ -52,7 +52,6 @@ private async Task GetScriptArgumentsAsync( { var variableValue = await context.GetVariableAsync(settings.InputVariables[i], cancellationToken); obj[settings.InputVariables[i]] = variableValue; - } } return obj; @@ -71,7 +70,7 @@ private async Task SetScriptResultAsync( } } - private JObject CopyProperties(JObject arguments) + private JObject CopyPropertiesToObject(JObject arguments) { var obj = new JObject(); foreach (var property in arguments.Properties()) From 1104e7276d01a2f222bd3fc46205be6f997776b9 Mon Sep 17 00:00:00 2001 From: "dante.barbosa" Date: Mon, 29 Apr 2024 14:23:18 -0300 Subject: [PATCH 09/13] 630626 - Improve unit tests and error texts --- .../Actions/ExecuteTemplateActionTests.cs | 47 +++++++++++++++---- .../ExecuteTemplate/ExecuteTemplateAction.cs | 22 +++++---- 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs b/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs index d415adc9..17a84308 100644 --- a/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs +++ b/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs @@ -17,7 +17,7 @@ public class ExecuteTemplateActionTests : ActionTestsBase private ExecuteTemplateAction GetTarget() { - return new ExecuteTemplateAction(Handlebars, new ConventionsConfiguration(), Substitute.For()); + return new ExecuteTemplateAction(Handlebars,Substitute.For()); } [Fact] @@ -48,13 +48,13 @@ public async Task ExecuteTemplateShouldSuccess() public async Task ExecuteTemplateWithObjectAsPropertyShouldSuccess() { //Arrange - var variableObj = "{ \"people\": [{\"name\": \"TestName\", \"city\": \"Aracaju\"}] }"; + var variableObj = "{ \"people\": [{\"name\": \"TestName\", \"city\": \"Aracaju\"}, {\"name\": \"TestName2\", \"city\": \"Bahia\"}] }"; var outputVariable = ""; Context.GetVariableAsync(nameof(variableObj), CancellationToken).Returns(variableObj); var settings = new ExecuteTemplateSettings { InputVariables = new []{ nameof(variableObj) }, - Template = "Names: {{#each people}}{{name}} living in {{city}}{{/each}}", + Template = "Names: {{#each people}}{{name}} living in {{city}} {{/each}}", OutputVariable = outputVariable }; @@ -72,14 +72,14 @@ public async Task ExecuteTemplateWithObjectAndStringVariablesAsPropertyShouldSuc { //Arrange var variableName = "Peoples:"; - var variableObj = "{ \"people\": [{\"name\": \"Carlos\", \"city\": \"Aracaju\"}] }"; + var variableObj = "{ \"people\": [{\"name\": \"TestName\", \"city\": \"Aracaju\"}, {\"name\": \"TestName2\", \"city\": \"Bahia\"}] }"; var outputVariable = ""; Context.GetVariableAsync(nameof(variableName), CancellationToken).Returns(variableName); Context.GetVariableAsync(nameof(variableObj), CancellationToken).Returns(variableObj); var settings = new ExecuteTemplateSettings { InputVariables = new []{ nameof(variableName), nameof(variableObj) }, - Template = $"{{{{{nameof(variableName)}}}}} {{{{#each people}}}}{{{{name}}}} living in {{{{city}}}}{{{{/each}}}}", + Template = $"{{{{{nameof(variableName)}}}}} {{{{#each people}}}}{{{{name}}}} living in {{{{city}}}} {{{{/each}}}}", OutputVariable = outputVariable }; @@ -93,13 +93,13 @@ public async Task ExecuteTemplateWithObjectAndStringVariablesAsPropertyShouldSuc } [Fact] - public async Task ExecuteTemplateShouldFail() + public async Task ExecuteTemplateErrorHandlebarsParseShouldFail() { //Arrange var variableName = "TestName"; var outputVariable = ""; Context.GetVariableAsync(nameof(variableName), CancellationToken).Returns(variableName); - Handlebars.Compile("").ThrowsForAnyArgs(new HandlebarsCompilerException("could not be converted to an expression")); + Handlebars.Compile("").ThrowsForAnyArgs(new HandlebarsParserException("could not be converted to an expression")); var settings = new ExecuteTemplateSettings { InputVariables = new []{ nameof(variableName) }, @@ -112,9 +112,8 @@ public async Task ExecuteTemplateShouldFail() try { await action.ExecuteAsync(Context, settings, CancellationToken); - throw new Exception("The template was executed"); } - catch (HandlebarsCompilerException ex) + catch (HandlebarsParserException ex) { ex.Message.ShouldContain("could not be converted to an expression"); } @@ -122,5 +121,35 @@ public async Task ExecuteTemplateShouldFail() Handlebars.Received(1).Compile(settings.Template); await Context.Received(0).SetVariableAsync(Arg.Any(), Arg.Any(), CancellationToken, Arg.Any()); } + + [Fact] + public async Task ExecuteTemplateErrorHandlebarsExecutionShouldFail() + { + //Arrange + var variableName = "TestName"; + var outputVariable = ""; + Context.GetVariableAsync(nameof(variableName), CancellationToken).Returns(variableName); + Handlebars.Compile("").ThrowsForAnyArgs(new Exception("Error executing the template")); + var settings = new ExecuteTemplateSettings + { + InputVariables = new []{ nameof(variableName) }, + Template = $"Name: {{{{nameof(variableName)}}}}", + OutputVariable = outputVariable + }; + + //Act + var action = GetTarget(); + try + { + await action.ExecuteAsync(Context, settings, CancellationToken); + } + catch (Exception ex) + { + ex.Message.ShouldContain("Error executing the template"); + } + + Handlebars.Received(1).Compile(settings.Template); + await Context.Received(0).SetVariableAsync(Arg.Any(), Arg.Any(), CancellationToken, Arg.Any()); + } } } \ No newline at end of file diff --git a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs index 4af1db58..227866bc 100644 --- a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs +++ b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs @@ -12,30 +12,34 @@ namespace Take.Blip.Builder.Actions.ExecuteTemplate { public class ExecuteTemplateAction : ActionBase { - private readonly IConfiguration _configuration; private readonly ILogger _logger; private readonly IHandlebars _handlebars; - public ExecuteTemplateAction(IHandlebars handlebars, IConfiguration configuration, ILogger logger) : base(nameof(ExecuteTemplateAction)) + public ExecuteTemplateAction(IHandlebars handlebars, ILogger logger) : base(nameof(ExecuteTemplateAction)) { - _configuration = configuration; _logger = logger; _handlebars = handlebars; } public override async Task ExecuteAsync(IContext context, ExecuteTemplateSettings settings, CancellationToken cancellationToken) { - string result; - var arguments = await GetScriptArgumentsAsync(context, settings, cancellationToken); - try + var result = string.Empty; + try { - var obj = CopyPropertiesToObject(arguments); + var arguments = await GetScriptArgumentsAsync(context, settings, cancellationToken); + var obj = CopyArgumentsToObject(arguments); var template = _handlebars.Compile(settings.Template); result = template(obj); } catch (Exception ex) { - _logger.Error(ex, "Unexpected error while trying to execute Handlebars template"); + if (ex is HandlebarsParserException) + { + _logger.Error(ex, "Unexpected error while trying to parse Handlebars template"); + throw; + } + + _logger.Error(ex, "Unexpected error while execute action Execute Template"); throw; } @@ -70,7 +74,7 @@ private async Task SetScriptResultAsync( } } - private JObject CopyPropertiesToObject(JObject arguments) + private JObject CopyArgumentsToObject(JObject arguments) { var obj = new JObject(); foreach (var property in arguments.Properties()) From 9a9bb98d489cb9f16b92b544b71c5736edf635f7 Mon Sep 17 00:00:00 2001 From: "dante.barbosa" Date: Thu, 2 May 2024 09:38:38 -0300 Subject: [PATCH 10/13] #630626 - Improve validations --- .../Actions/ExecuteTemplateActionTests.cs | 25 ++++++++++++++++--- .../ExecuteTemplate/ExecuteTemplateAction.cs | 25 +++++++++++-------- .../ExecuteTemplateSettings.cs | 1 - 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs b/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs index 17a84308..ecc7e2de 100644 --- a/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs +++ b/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs @@ -1,6 +1,7 @@ using System; using System.Threading.Tasks; using HandlebarsDotNet; +using Newtonsoft.Json.Linq; using NSubstitute; using NSubstitute.ExceptionExtensions; using Serilog; @@ -26,7 +27,12 @@ public async Task ExecuteTemplateShouldSuccess() //Arrange var variableName = "TestName"; var outputVariable = ""; - Context.GetVariableAsync(nameof(variableName), CancellationToken).Returns(variableName); + Context.GetVariableAsync(nameof(variableName), CancellationToken).Returns(variableName); + + var templateResult = "TemplateResult"; + var handlebarsTemplate = Substitute.For>(); + handlebarsTemplate(Arg.Any()).Returns("TemplateResult"); + Handlebars.Compile(Arg.Any()).Returns(handlebarsTemplate); var settings = new ExecuteTemplateSettings { @@ -41,7 +47,7 @@ public async Task ExecuteTemplateShouldSuccess() // Assert Handlebars.Received(1).Compile(settings.Template); - await Context.Received(1).SetVariableAsync(Arg.Any(), Arg.Any(), CancellationToken, Arg.Any()); + await Context.Received(1).SetVariableAsync(Arg.Any(), Arg.Is(templateResult), CancellationToken, Arg.Any()); } [Fact] @@ -51,6 +57,12 @@ public async Task ExecuteTemplateWithObjectAsPropertyShouldSuccess() var variableObj = "{ \"people\": [{\"name\": \"TestName\", \"city\": \"Aracaju\"}, {\"name\": \"TestName2\", \"city\": \"Bahia\"}] }"; var outputVariable = ""; Context.GetVariableAsync(nameof(variableObj), CancellationToken).Returns(variableObj); + + var templateResult = "TemplateResult"; + var handlebarsTemplate = Substitute.For>(); + handlebarsTemplate(Arg.Any()).Returns("TemplateResult"); + Handlebars.Compile(Arg.Any()).Returns(handlebarsTemplate); + var settings = new ExecuteTemplateSettings { InputVariables = new []{ nameof(variableObj) }, @@ -64,7 +76,7 @@ public async Task ExecuteTemplateWithObjectAsPropertyShouldSuccess() // Assert Handlebars.Received(1).Compile(settings.Template); - await Context.Received(1).SetVariableAsync(Arg.Any(), Arg.Any(), CancellationToken, Arg.Any()); + await Context.Received(1).SetVariableAsync(Arg.Any(), Arg.Is(templateResult), CancellationToken, Arg.Any()); } [Fact] @@ -76,6 +88,11 @@ public async Task ExecuteTemplateWithObjectAndStringVariablesAsPropertyShouldSuc var outputVariable = ""; Context.GetVariableAsync(nameof(variableName), CancellationToken).Returns(variableName); Context.GetVariableAsync(nameof(variableObj), CancellationToken).Returns(variableObj); + + var templateResult = "TemplateResult"; + var handlebarsTemplate = Substitute.For>(); + handlebarsTemplate(Arg.Any()).Returns("TemplateResult"); + Handlebars.Compile(Arg.Any()).Returns(handlebarsTemplate); var settings = new ExecuteTemplateSettings { InputVariables = new []{ nameof(variableName), nameof(variableObj) }, @@ -89,7 +106,7 @@ public async Task ExecuteTemplateWithObjectAndStringVariablesAsPropertyShouldSuc // Assert Handlebars.Received(1).Compile(settings.Template); - await Context.Received(1).SetVariableAsync(Arg.Any(), Arg.Any(), CancellationToken, Arg.Any()); + await Context.Received(1).SetVariableAsync(Arg.Any(), Arg.Is(templateResult), CancellationToken, Arg.Any()); } [Fact] diff --git a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs index 227866bc..f00def97 100644 --- a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs +++ b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs @@ -2,11 +2,11 @@ using System.Threading; using System.Threading.Tasks; using HandlebarsDotNet; -using HandlebarsDotNet.Extension.Json; +using Lime.Protocol; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Serilog; -using Take.Blip.Builder.Hosting; +using Takenet.Iris.Messaging; namespace Take.Blip.Builder.Actions.ExecuteTemplate { @@ -35,11 +35,11 @@ public override async Task ExecuteAsync(IContext context, ExecuteTemplateSetting { if (ex is HandlebarsParserException) { - _logger.Error(ex, "Unexpected error while trying to parse Handlebars template"); + _logger.Warning(ex, "Unexpected error while trying to parse Handlebars template"); throw; } - _logger.Error(ex, "Unexpected error while execute action Execute Template"); + _logger.Warning(ex, "Unexpected error while execute action Execute Template"); throw; } @@ -50,13 +50,16 @@ private async Task GetScriptArgumentsAsync( IContext context, ExecuteTemplateSettings settings, CancellationToken cancellationToken) { var obj = new JObject(); - if (settings.InputVariables != null && settings.InputVariables.Length > 0) + + if (settings.InputVariables.IsNullOrEmpty() && settings.InputVariables.Length <= 0) { - for (int i = 0; i < settings.InputVariables.Length; i++) - { - var variableValue = await context.GetVariableAsync(settings.InputVariables[i], cancellationToken); - obj[settings.InputVariables[i]] = variableValue; - } + return obj; + } + + foreach (var variable in settings.InputVariables) + { + var variableValue = await context.GetVariableAsync(variable, cancellationToken); + obj[variable] = variableValue; } return obj; } @@ -64,7 +67,7 @@ private async Task GetScriptArgumentsAsync( private async Task SetScriptResultAsync( IContext context, ExecuteTemplateSettings settings, string result, CancellationToken cancellationToken) { - if (result != null) + if (!result.IsNullOrEmpty()) { await context.SetVariableAsync(settings.OutputVariable, result, cancellationToken); } diff --git a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateSettings.cs b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateSettings.cs index 26074b7b..7380518a 100644 --- a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateSettings.cs +++ b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateSettings.cs @@ -1,5 +1,4 @@ using System.ComponentModel.DataAnnotations; -using HandlebarsDotNet; using Take.Blip.Builder.Models; namespace Take.Blip.Builder.Actions.ExecuteTemplate From d3416e113179ffa172520acdebd62a9d7bfcf690 Mon Sep 17 00:00:00 2001 From: "dante.barbosa" Date: Thu, 2 May 2024 09:39:07 -0300 Subject: [PATCH 11/13] #630626 - Remove unecessary usings --- .../Actions/ExecuteTemplateActionTests.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs b/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs index ecc7e2de..adac8a4b 100644 --- a/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs +++ b/src/Take.Blip.Builder.UnitTests/Actions/ExecuteTemplateActionTests.cs @@ -1,12 +1,10 @@ using System; using System.Threading.Tasks; using HandlebarsDotNet; -using Newtonsoft.Json.Linq; using NSubstitute; using NSubstitute.ExceptionExtensions; using Serilog; using Take.Blip.Builder.Actions.ExecuteTemplate; -using Take.Blip.Builder.Hosting; using Xunit; using Shouldly; From 2f777ab5ad1e6e879a0ded1400fe2f800cc76b26 Mon Sep 17 00:00:00 2001 From: "dante.barbosa" Date: Thu, 2 May 2024 12:14:17 -0300 Subject: [PATCH 12/13] 630626 - Improve json deserialize --- .../ExecuteTemplate/ExecuteTemplateAction.cs | 37 +++++++------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs index f00def97..5253d3c1 100644 --- a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs +++ b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs @@ -1,11 +1,13 @@ using System; using System.Threading; using System.Threading.Tasks; +using Esprima; using HandlebarsDotNet; using Lime.Protocol; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Serilog; +using Take.Blip.Builder.Utils; using Takenet.Iris.Messaging; namespace Take.Blip.Builder.Actions.ExecuteTemplate @@ -24,7 +26,7 @@ public ExecuteTemplateAction(IHandlebars handlebars, ILogger logger) : base(name public override async Task ExecuteAsync(IContext context, ExecuteTemplateSettings settings, CancellationToken cancellationToken) { var result = string.Empty; - try + try { var arguments = await GetScriptArgumentsAsync(context, settings, cancellationToken); var obj = CopyArgumentsToObject(arguments); @@ -51,7 +53,7 @@ private async Task GetScriptArgumentsAsync( { var obj = new JObject(); - if (settings.InputVariables.IsNullOrEmpty() && settings.InputVariables.Length <= 0) + if (settings.InputVariables.IsNullOrEmpty()) { return obj; } @@ -67,13 +69,13 @@ private async Task GetScriptArgumentsAsync( private async Task SetScriptResultAsync( IContext context, ExecuteTemplateSettings settings, string result, CancellationToken cancellationToken) { - if (!result.IsNullOrEmpty()) + if (result.IsNullOrEmpty()) { - await context.SetVariableAsync(settings.OutputVariable, result, cancellationToken); + await context.DeleteVariableAsync(settings.OutputVariable, cancellationToken); } else { - await context.DeleteVariableAsync(settings.OutputVariable, cancellationToken); + await context.SetVariableAsync(settings.OutputVariable, result, cancellationToken); } } @@ -82,33 +84,20 @@ private JObject CopyArgumentsToObject(JObject arguments) var obj = new JObject(); foreach (var property in arguments.Properties()) { - var success = TryParseJson(property.Value.ToString(), out var jObject); - if (success) + try { - foreach (var item in jObject) + var deserializeJson = JsonConvert.DeserializeObject(property.Value.ToString(), JsonSerializerSettingsContainer.Settings); + if (deserializeJson != null) { - obj[item.Key] = item.Value; + obj.Merge(deserializeJson); } - } - else + } catch (JsonReaderException) { obj[property.Name] = property.Value; - } + } } return obj; } - - private bool TryParseJson(string json, out T result) - { - bool success = true; - var settings = new JsonSerializerSettings - { - Error = (sender, args) => { success = false; args.ErrorContext.Handled = true; }, - MissingMemberHandling = MissingMemberHandling.Error - }; - result = JsonConvert.DeserializeObject(json, settings); - return success; - } } } \ No newline at end of file From 5a0138a6da77fbbd006da31f40c1e4715429d8b2 Mon Sep 17 00:00:00 2001 From: "dante.barbosa" Date: Thu, 2 May 2024 16:42:57 -0300 Subject: [PATCH 13/13] 630626 - Improve variable name --- .../Actions/ExecuteTemplate/ExecuteTemplateAction.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs index 5253d3c1..80641784 100644 --- a/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs +++ b/src/Take.Blip.Builder/Actions/ExecuteTemplate/ExecuteTemplateAction.cs @@ -86,10 +86,10 @@ private JObject CopyArgumentsToObject(JObject arguments) { try { - var deserializeJson = JsonConvert.DeserializeObject(property.Value.ToString(), JsonSerializerSettingsContainer.Settings); - if (deserializeJson != null) + var deserializedJson = JsonConvert.DeserializeObject(property.Value.ToString(), JsonSerializerSettingsContainer.Settings); + if (deserializedJson != null) { - obj.Merge(deserializeJson); + obj.Merge(deserializedJson); } } catch (JsonReaderException) {