From dcd452866cc107da1d3e59006dcecf875b71149b Mon Sep 17 00:00:00 2001 From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com> Date: Fri, 28 Jan 2022 12:14:28 -0500 Subject: [PATCH 1/7] Add types for Minimal API --- .../MinimalApiTwiMLResults.cs | 40 +++++++++++++++++++ .../Twilio.AspNet.Core.csproj | 3 +- src/Twilio.AspNet.sln | 6 +++ 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 src/Twilio.AspNet.Core/MinimalApiTwiMLResults.cs diff --git a/src/Twilio.AspNet.Core/MinimalApiTwiMLResults.cs b/src/Twilio.AspNet.Core/MinimalApiTwiMLResults.cs new file mode 100644 index 0000000..42dbdf8 --- /dev/null +++ b/src/Twilio.AspNet.Core/MinimalApiTwiMLResults.cs @@ -0,0 +1,40 @@ +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Twilio.TwiML; + +namespace Twilio.AspNet.Core.MinimalApi +{ + public static class ResultsExtensions + { + public static IResult TwiML(this IResultExtensions resultExtensions, MessagingResponse response) + => new TwiMLResult(response); + + public static IResult TwiML(this IResultExtensions resultExtensions, VoiceResponse response) + => new TwiMLResult(response); + } + + public class TwiMLResult : IResult + { + private string twiML; + + public TwiMLResult(MessagingResponse response) + { + twiML = response?.ToString(); + } + + public TwiMLResult(VoiceResponse response) + { + twiML = response?.ToString(); + } + + public Task ExecuteAsync(HttpContext httpContext) + { + twiML ??= ""; + + httpContext.Response.ContentType = "application/xml"; + httpContext.Response.ContentLength = Encoding.UTF8.GetByteCount(twiML); + return httpContext.Response.WriteAsync(twiML); + } + } +} \ No newline at end of file diff --git a/src/Twilio.AspNet.Core/Twilio.AspNet.Core.csproj b/src/Twilio.AspNet.Core/Twilio.AspNet.Core.csproj index 85be85e..11024bb 100644 --- a/src/Twilio.AspNet.Core/Twilio.AspNet.Core.csproj +++ b/src/Twilio.AspNet.Core/Twilio.AspNet.Core.csproj @@ -1,6 +1,6 @@ - netstandard1.6 + net6.0 Library Twilio.AspNet.Core 5.68.3 @@ -17,6 +17,7 @@ 5.68.3 + diff --git a/src/Twilio.AspNet.sln b/src/Twilio.AspNet.sln index 64f3782..b27c2b0 100644 --- a/src/Twilio.AspNet.sln +++ b/src/Twilio.AspNet.sln @@ -17,6 +17,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Twilio.AspNet.Core", "Twili EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Twilio.AspNet.Mvc.UnitTests", "Twilio.AspNet.Mvc.UnitTests\Twilio.AspNet.Mvc.UnitTests.csproj", "{B92BDA0D-AD69-4756-BBD6-6E77C4B51906}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Twilio.AspNet.Core.UnitTests", "Twilio.AspNet.Core.UnitTests\Twilio.AspNet.Core.UnitTests.csproj", "{FABCBDFB-E9F8-4B0F-9657-7B156CDA98C2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -39,6 +41,10 @@ Global {B92BDA0D-AD69-4756-BBD6-6E77C4B51906}.Debug|Any CPU.Build.0 = Debug|Any CPU {B92BDA0D-AD69-4756-BBD6-6E77C4B51906}.Release|Any CPU.ActiveCfg = Release|Any CPU {B92BDA0D-AD69-4756-BBD6-6E77C4B51906}.Release|Any CPU.Build.0 = Release|Any CPU + {FABCBDFB-E9F8-4B0F-9657-7B156CDA98C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FABCBDFB-E9F8-4B0F-9657-7B156CDA98C2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FABCBDFB-E9F8-4B0F-9657-7B156CDA98C2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FABCBDFB-E9F8-4B0F-9657-7B156CDA98C2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 25d3ab7c2a94b859e30d635e1fa7db971f903840 Mon Sep 17 00:00:00 2001 From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com> Date: Mon, 31 Jan 2022 16:52:11 -0500 Subject: [PATCH 2/7] Use multiple target frameworks to maintain backward compatibility with netstandard1.6 and add types for net6.0 --- src/Twilio.AspNet.Core/MinimalApiTwiMLResults.cs | 4 +++- src/Twilio.AspNet.Core/Twilio.AspNet.Core.csproj | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Twilio.AspNet.Core/MinimalApiTwiMLResults.cs b/src/Twilio.AspNet.Core/MinimalApiTwiMLResults.cs index 42dbdf8..e0a8af9 100644 --- a/src/Twilio.AspNet.Core/MinimalApiTwiMLResults.cs +++ b/src/Twilio.AspNet.Core/MinimalApiTwiMLResults.cs @@ -1,3 +1,4 @@ +#if NET6_0 using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; @@ -37,4 +38,5 @@ public Task ExecuteAsync(HttpContext httpContext) return httpContext.Response.WriteAsync(twiML); } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/src/Twilio.AspNet.Core/Twilio.AspNet.Core.csproj b/src/Twilio.AspNet.Core/Twilio.AspNet.Core.csproj index 11024bb..529fbe1 100644 --- a/src/Twilio.AspNet.Core/Twilio.AspNet.Core.csproj +++ b/src/Twilio.AspNet.Core/Twilio.AspNet.Core.csproj @@ -1,6 +1,6 @@ - net6.0 + netstandard1.6;net6.0 Library Twilio.AspNet.Core 5.68.3 @@ -17,7 +17,8 @@ 5.68.3 - + From 30e6e62da54c1e00b97ff11735feeeee50b19d4a Mon Sep 17 00:00:00 2001 From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com> Date: Fri, 11 Feb 2022 16:23:00 -0500 Subject: [PATCH 3/7] Bump version number + Update build script to use dotnet CLI more The msbuild commands would not correctly compile Twilio.AspNet.Core using NET6.0, but the dotnet CLI does equivalent commands does. --- build.ps1 | 21 +++++++++---------- .../Twilio.AspNet.Common.csproj | 2 +- .../MinimalApiTwiMLResults.cs | 2 +- .../Twilio.AspNet.Core.csproj | 11 +++++----- .../Properties/AssemblyInfo.cs | 5 +++-- .../Twilio.AspNet.Mvc.UnitTests.csproj | 5 +++-- .../packages.config | 2 +- .../Properties/AssemblyInfo.cs | 5 +++-- .../Twilio.AspNet.Mvc.csproj | 9 ++++---- src/Twilio.AspNet.Mvc/packages.config | 4 ++-- 10 files changed, 34 insertions(+), 32 deletions(-) diff --git a/build.ps1 b/build.ps1 index 6afb528..faa33f1 100644 --- a/build.ps1 +++ b/build.ps1 @@ -12,7 +12,7 @@ function Stop-Script($exitCode) { if ($exitCode -eq 0) { Write-Host "SUCCESS" -ForegroundColor Green } else { - Write-Host "FAILIURE" -ForegroundColor Red + Write-Host "FAILURE" -ForegroundColor Red } exit $exitCode } @@ -31,23 +31,23 @@ Remove-EntirePath .\Twilio.AspNet.Mvc\obj # Build Twilio.AspNet.Common first Push-Location .\Twilio.AspNet.Common -dotnet restore +dotnet restore -v m if ($lastExitCode -ne 0) { Stop-Script $lastExitCode } -dotnet msbuild /t:clean /verbosity:minimal +dotnet clean -v m if ($lastExitCode -ne 0) { Stop-Script $lastExitCode } -dotnet msbuild /p:Configuration=Release /verbosity:minimal +dotnet build -c Release -v m if ($lastExitCode -ne 0) { Stop-Script $lastExitCode } -dotnet msbuild /t:pack /p:Configuration=Release /p:OutputPath=..\..\ /verbosity:minimal +dotnet pack -c Release -o ..\..\ -v m if ($lastExitCode -ne 0) { Stop-Script $lastExitCode } Pop-Location -& $nugetExe ('restore', '-Source', ($PSScriptRoot + ';https://api.nuget.org/v3/index.json')) +dotnet restore -v m --source $($PSScriptRoot + ';https://api.nuget.org/v3/index.json') if ($lastExitCode -ne 0) { Stop-Script $lastExitCode } -dotnet msbuild /t:clean /verbosity:minimal +dotnet clean -v m if ($lastExitCode -ne 0) { Stop-Script $lastExitCode } -dotnet msbuild /p:Configuration=Release /verbosity:minimal +dotnet build -c Release -v m if ($lastExitCode -ne 0) { Stop-Script $lastExitCode } # Run tests @@ -55,14 +55,13 @@ if ($lastExitCode -ne 0) { Stop-Script $lastExitCode } if ($lastExitCode -ne 0) { Stop-Script $lastExitCode } Push-Location .\Twilio.AspNet.Core.UnitTests -dotnet test +dotnet test -v m if ($lastExitCode -ne 0) { Stop-Script $lastExitCode } Pop-Location # Create the NuGet Packages - Push-Location .\Twilio.AspNet.Core -dotnet msbuild /t:pack /p:Configuration=Release /p:OutputPath=..\..\ /verbosity:minimal +dotnet pack -c Release -o ..\..\ -v m if ($lastExitCode -ne 0) { Stop-Script $lastExitCode } Pop-Location diff --git a/src/Twilio.AspNet.Common/Twilio.AspNet.Common.csproj b/src/Twilio.AspNet.Common/Twilio.AspNet.Common.csproj index 337fd84..b729548 100644 --- a/src/Twilio.AspNet.Common/Twilio.AspNet.Common.csproj +++ b/src/Twilio.AspNet.Common/Twilio.AspNet.Common.csproj @@ -3,7 +3,7 @@ netstandard1.0;net45 Library Twilio.AspNet.Common - 5.68.3 + 5.71.0 Twilio Twilio request classes for handling Twilio webhooks. false diff --git a/src/Twilio.AspNet.Core/MinimalApiTwiMLResults.cs b/src/Twilio.AspNet.Core/MinimalApiTwiMLResults.cs index e0a8af9..f07d7c7 100644 --- a/src/Twilio.AspNet.Core/MinimalApiTwiMLResults.cs +++ b/src/Twilio.AspNet.Core/MinimalApiTwiMLResults.cs @@ -1,4 +1,4 @@ -#if NET6_0 +#if NET6_0_OR_GREATER using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; diff --git a/src/Twilio.AspNet.Core/Twilio.AspNet.Core.csproj b/src/Twilio.AspNet.Core/Twilio.AspNet.Core.csproj index 529fbe1..71eefcc 100644 --- a/src/Twilio.AspNet.Core/Twilio.AspNet.Core.csproj +++ b/src/Twilio.AspNet.Core/Twilio.AspNet.Core.csproj @@ -3,7 +3,7 @@ netstandard1.6;net6.0 Library Twilio.AspNet.Core - 5.68.3 + 5.71.0 Twilio Twilio helpers for ASP.NET Core 1.0 to 2.x. false @@ -14,14 +14,13 @@ http://github.com/twilio/twilio-aspnet https://s3.amazonaws.com/com.twilio.prod.twilio-docs/images/twilio-icon-64x64.png icon.png - 5.68.3 + 5.71.0 - + - - + + \ No newline at end of file diff --git a/src/Twilio.AspNet.Mvc.UnitTests/Properties/AssemblyInfo.cs b/src/Twilio.AspNet.Mvc.UnitTests/Properties/AssemblyInfo.cs index b2635b9..703e02e 100644 --- a/src/Twilio.AspNet.Mvc.UnitTests/Properties/AssemblyInfo.cs +++ b/src/Twilio.AspNet.Mvc.UnitTests/Properties/AssemblyInfo.cs @@ -14,6 +14,7 @@ [assembly: Guid("b92bda0d-ad69-4756-bbd6-6e77c4b51906")] -[assembly: AssemblyVersion("5.68.3")] -[assembly: AssemblyFileVersion("5.68.3")] +[assembly: AssemblyVersion("5.71.0")] +[assembly: AssemblyFileVersion("5.71.0")] + diff --git a/src/Twilio.AspNet.Mvc.UnitTests/Twilio.AspNet.Mvc.UnitTests.csproj b/src/Twilio.AspNet.Mvc.UnitTests/Twilio.AspNet.Mvc.UnitTests.csproj index ace7714..f2cbde8 100644 --- a/src/Twilio.AspNet.Mvc.UnitTests/Twilio.AspNet.Mvc.UnitTests.csproj +++ b/src/Twilio.AspNet.Mvc.UnitTests/Twilio.AspNet.Mvc.UnitTests.csproj @@ -95,8 +95,8 @@ - - ..\packages\Twilio.5.68.1\lib\net451\Twilio.dll + + ..\packages\Twilio.5.71.0\lib\net451\Twilio.dll ..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll @@ -147,3 +147,4 @@ + diff --git a/src/Twilio.AspNet.Mvc.UnitTests/packages.config b/src/Twilio.AspNet.Mvc.UnitTests/packages.config index 88396b3..440d9fe 100644 --- a/src/Twilio.AspNet.Mvc.UnitTests/packages.config +++ b/src/Twilio.AspNet.Mvc.UnitTests/packages.config @@ -12,7 +12,7 @@ - + diff --git a/src/Twilio.AspNet.Mvc/Properties/AssemblyInfo.cs b/src/Twilio.AspNet.Mvc/Properties/AssemblyInfo.cs index bb1c033..775a76d 100644 --- a/src/Twilio.AspNet.Mvc/Properties/AssemblyInfo.cs +++ b/src/Twilio.AspNet.Mvc/Properties/AssemblyInfo.cs @@ -31,6 +31,7 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("5.68.3")] -[assembly: AssemblyFileVersion("5.68.3")] +[assembly: AssemblyVersion("5.71.0")] +[assembly: AssemblyFileVersion("5.71.0")] + diff --git a/src/Twilio.AspNet.Mvc/Twilio.AspNet.Mvc.csproj b/src/Twilio.AspNet.Mvc/Twilio.AspNet.Mvc.csproj index 01a2e4d..1a81d06 100644 --- a/src/Twilio.AspNet.Mvc/Twilio.AspNet.Mvc.csproj +++ b/src/Twilio.AspNet.Mvc/Twilio.AspNet.Mvc.csproj @@ -84,11 +84,11 @@ - - ..\packages\Twilio.5.68.1\lib\net451\Twilio.dll + + ..\packages\Twilio.5.71.0\lib\net451\Twilio.dll - - ..\packages\Twilio.AspNet.Common.5.68.3\lib\net45\Twilio.AspNet.Common.dll + + ..\packages\Twilio.AspNet.Common.5.71.0\lib\net45\Twilio.AspNet.Common.dll @@ -121,3 +121,4 @@ + diff --git a/src/Twilio.AspNet.Mvc/packages.config b/src/Twilio.AspNet.Mvc/packages.config index e51c25b..0d1b9ed 100644 --- a/src/Twilio.AspNet.Mvc/packages.config +++ b/src/Twilio.AspNet.Mvc/packages.config @@ -8,6 +8,6 @@ - - + + \ No newline at end of file From 44ba27e81846148e3d29d746fa1bc612e2bed9eb Mon Sep 17 00:00:00 2001 From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com> Date: Wed, 23 Feb 2022 18:59:38 -0500 Subject: [PATCH 4/7] Add test for MinimalApiTwiMLResult --- .../MinimalApiTwiMLResultTests.cs | 30 +++++++++++++++++++ .../RequestValidationHelperTests.cs | 2 +- .../Twilio.AspNet.Core.UnitTests.csproj | 1 - ...iMLResults.cs => MinimalApiTwiMLResult.cs} | 0 src/Twilio.AspNet.sln | 17 ++++++++++- src/testapps/dotnet6/Program.cs | 13 +++++++- 6 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 src/Twilio.AspNet.Core.UnitTests/MinimalApiTwiMLResultTests.cs rename src/Twilio.AspNet.Core/{MinimalApiTwiMLResults.cs => MinimalApiTwiMLResult.cs} (100%) diff --git a/src/Twilio.AspNet.Core.UnitTests/MinimalApiTwiMLResultTests.cs b/src/Twilio.AspNet.Core.UnitTests/MinimalApiTwiMLResultTests.cs new file mode 100644 index 0000000..67f42a9 --- /dev/null +++ b/src/Twilio.AspNet.Core.UnitTests/MinimalApiTwiMLResultTests.cs @@ -0,0 +1,30 @@ +using System.IO; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Twilio.AspNet.Core.MinimalApi; +using Twilio.TwiML; +using Xunit; + +namespace Twilio.AspNet.Core.UnitTests; + +// ReSharper disable once InconsistentNaming +public class MinimalApiTwiMLResultTests +{ + [Fact] + public async Task TestTwimlResultWritesToResponseBody() + { + var httpContext = new DefaultHttpContext(); + httpContext.Response.Body = new MemoryStream(); + + var twiml = GetVoiceResponse(); + var twimlResult = Results.Extensions.TwiML(twiml); + await twimlResult.ExecuteAsync(httpContext); + + httpContext.Response.Body.Seek(0, SeekOrigin.Begin); + var reader = new StreamReader(httpContext.Response.Body); + var responseBody = await reader.ReadToEndAsync(); + Assert.Equal(twiml.ToString(), responseBody); + } + + private static VoiceResponse GetVoiceResponse() => new TwiML.VoiceResponse().Say("Hello World"); +} \ No newline at end of file diff --git a/src/Twilio.AspNet.Core.UnitTests/RequestValidationHelperTests.cs b/src/Twilio.AspNet.Core.UnitTests/RequestValidationHelperTests.cs index 0c64007..0ba28b4 100644 --- a/src/Twilio.AspNet.Core.UnitTests/RequestValidationHelperTests.cs +++ b/src/Twilio.AspNet.Core.UnitTests/RequestValidationHelperTests.cs @@ -9,7 +9,7 @@ using Twilio.AspNet.Core; using Xunit; -namespace Twilio.AspNet.Mvc.UnitTests +namespace Twilio.AspNet.Core.UnitTests { public class ContextMocks { diff --git a/src/Twilio.AspNet.Core.UnitTests/Twilio.AspNet.Core.UnitTests.csproj b/src/Twilio.AspNet.Core.UnitTests/Twilio.AspNet.Core.UnitTests.csproj index c7be8a5..79a3cfe 100644 --- a/src/Twilio.AspNet.Core.UnitTests/Twilio.AspNet.Core.UnitTests.csproj +++ b/src/Twilio.AspNet.Core.UnitTests/Twilio.AspNet.Core.UnitTests.csproj @@ -3,7 +3,6 @@ net6.0 enable - false diff --git a/src/Twilio.AspNet.Core/MinimalApiTwiMLResults.cs b/src/Twilio.AspNet.Core/MinimalApiTwiMLResult.cs similarity index 100% rename from src/Twilio.AspNet.Core/MinimalApiTwiMLResults.cs rename to src/Twilio.AspNet.Core/MinimalApiTwiMLResult.cs diff --git a/src/Twilio.AspNet.sln b/src/Twilio.AspNet.sln index b27c2b0..18b6ac9 100644 --- a/src/Twilio.AspNet.sln +++ b/src/Twilio.AspNet.sln @@ -17,7 +17,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Twilio.AspNet.Core", "Twili EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Twilio.AspNet.Mvc.UnitTests", "Twilio.AspNet.Mvc.UnitTests\Twilio.AspNet.Mvc.UnitTests.csproj", "{B92BDA0D-AD69-4756-BBD6-6E77C4B51906}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Twilio.AspNet.Core.UnitTests", "Twilio.AspNet.Core.UnitTests\Twilio.AspNet.Core.UnitTests.csproj", "{FABCBDFB-E9F8-4B0F-9657-7B156CDA98C2}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testapps", "testapps", "{06967A7D-E066-42D8-8915-5852EA932C6A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnet6", "testapps\dotnet6\dotnet6.csproj", "{131F1920-1002-4BF1-925C-1826F7422F03}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Twilio.AspNet.Core.UnitTests", "Twilio.AspNet.Core.UnitTests\Twilio.AspNet.Core.UnitTests.csproj", "{B3E732C9-27EF-4E96-B620-5B5DA57D9AD3}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -41,10 +45,18 @@ Global {B92BDA0D-AD69-4756-BBD6-6E77C4B51906}.Debug|Any CPU.Build.0 = Debug|Any CPU {B92BDA0D-AD69-4756-BBD6-6E77C4B51906}.Release|Any CPU.ActiveCfg = Release|Any CPU {B92BDA0D-AD69-4756-BBD6-6E77C4B51906}.Release|Any CPU.Build.0 = Release|Any CPU + {131F1920-1002-4BF1-925C-1826F7422F03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {131F1920-1002-4BF1-925C-1826F7422F03}.Debug|Any CPU.Build.0 = Debug|Any CPU + {131F1920-1002-4BF1-925C-1826F7422F03}.Release|Any CPU.ActiveCfg = Release|Any CPU + {131F1920-1002-4BF1-925C-1826F7422F03}.Release|Any CPU.Build.0 = Release|Any CPU {FABCBDFB-E9F8-4B0F-9657-7B156CDA98C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FABCBDFB-E9F8-4B0F-9657-7B156CDA98C2}.Debug|Any CPU.Build.0 = Debug|Any CPU {FABCBDFB-E9F8-4B0F-9657-7B156CDA98C2}.Release|Any CPU.ActiveCfg = Release|Any CPU {FABCBDFB-E9F8-4B0F-9657-7B156CDA98C2}.Release|Any CPU.Build.0 = Release|Any CPU + {B3E732C9-27EF-4E96-B620-5B5DA57D9AD3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B3E732C9-27EF-4E96-B620-5B5DA57D9AD3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B3E732C9-27EF-4E96-B620-5B5DA57D9AD3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B3E732C9-27EF-4E96-B620-5B5DA57D9AD3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -52,4 +64,7 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {7D0F9171-129A-4B05-809E-F501DBC23197} EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {131F1920-1002-4BF1-925C-1826F7422F03} = {06967A7D-E066-42D8-8915-5852EA932C6A} + EndGlobalSection EndGlobal diff --git a/src/testapps/dotnet6/Program.cs b/src/testapps/dotnet6/Program.cs index 0727468..f53fe5f 100644 --- a/src/testapps/dotnet6/Program.cs +++ b/src/testapps/dotnet6/Program.cs @@ -1,3 +1,6 @@ +using Twilio.AspNet.Core.MinimalApi; +using Twilio.TwiML; + var builder = WebApplication.CreateBuilder(args); // Add services to the container. @@ -24,4 +27,12 @@ name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); -app.Run(); +app.MapMethods("/minimal-sms", new[] {"get", "post"}, () => +{ + var messagingResponse = new MessagingResponse(); + messagingResponse.Message("The Robots are coming! Head for the hills!!"); + + return Results.Extensions.TwiML(messagingResponse); +}); + +app.Run(); \ No newline at end of file From 78069b8e57ad2a7d218ddc1b16a5e0ee00837ab8 Mon Sep 17 00:00:00 2001 From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com> Date: Wed, 23 Feb 2022 19:40:44 -0500 Subject: [PATCH 5/7] Test Messaging and Voice Response + use TwiML base type instead of subclasses --- .../MinimalApiTwiMLResultTests.cs | 20 +++-- .../MinimalApiTwiMLResult.cs | 73 ++++++++++++------- 2 files changed, 59 insertions(+), 34 deletions(-) diff --git a/src/Twilio.AspNet.Core.UnitTests/MinimalApiTwiMLResultTests.cs b/src/Twilio.AspNet.Core.UnitTests/MinimalApiTwiMLResultTests.cs index 67f42a9..5e58f79 100644 --- a/src/Twilio.AspNet.Core.UnitTests/MinimalApiTwiMLResultTests.cs +++ b/src/Twilio.AspNet.Core.UnitTests/MinimalApiTwiMLResultTests.cs @@ -1,4 +1,5 @@ -using System.IO; +using System; +using System.IO; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Twilio.AspNet.Core.MinimalApi; @@ -11,20 +12,27 @@ namespace Twilio.AspNet.Core.UnitTests; public class MinimalApiTwiMLResultTests { [Fact] - public async Task TestTwimlResultWritesToResponseBody() + public Task TestTwimlResultWritesVoiceResponseToResponseBody() => + ValidateTwimlResultWritesToResponseBody(GetVoiceResponse()); + + [Fact] + public Task TestTwimlResultWritesMessagingResponseToResponseBody() => + ValidateTwimlResultWritesToResponseBody(GetMessagingResponse()); + + private static async Task ValidateTwimlResultWritesToResponseBody(TwiML.TwiML twiMlResponse) { var httpContext = new DefaultHttpContext(); httpContext.Response.Body = new MemoryStream(); - var twiml = GetVoiceResponse(); - var twimlResult = Results.Extensions.TwiML(twiml); + var twimlResult = Results.Extensions.TwiML(twiMlResponse); await twimlResult.ExecuteAsync(httpContext); httpContext.Response.Body.Seek(0, SeekOrigin.Begin); var reader = new StreamReader(httpContext.Response.Body); var responseBody = await reader.ReadToEndAsync(); - Assert.Equal(twiml.ToString(), responseBody); + Assert.Equal(twiMlResponse.ToString(), responseBody); } - private static VoiceResponse GetVoiceResponse() => new TwiML.VoiceResponse().Say("Hello World"); + private static VoiceResponse GetVoiceResponse() => new VoiceResponse().Say("Hello World"); + private static MessagingResponse GetMessagingResponse() => new MessagingResponse().Message("Hello World"); } \ No newline at end of file diff --git a/src/Twilio.AspNet.Core/MinimalApiTwiMLResult.cs b/src/Twilio.AspNet.Core/MinimalApiTwiMLResult.cs index f07d7c7..6d1da8e 100644 --- a/src/Twilio.AspNet.Core/MinimalApiTwiMLResult.cs +++ b/src/Twilio.AspNet.Core/MinimalApiTwiMLResult.cs @@ -2,41 +2,58 @@ using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; -using Twilio.TwiML; -namespace Twilio.AspNet.Core.MinimalApi +// ReSharper disable once CheckNamespace +namespace Twilio.AspNet.Core.MinimalApi; + +/// +/// Adds extension methods to Results.Extensions to write TwiML objects to the HTTP response body +/// +public static class ResultsExtensions { - public static class ResultsExtensions - { - public static IResult TwiML(this IResultExtensions resultExtensions, MessagingResponse response) - => new TwiMLResult(response); + /// + /// Returns a TwiMLResult + /// + /// Results extensions interface + /// The TwiML to write to the HTTP response body + /// The TwiMLResult will write the TwiML to the HTTP response body + // ReSharper disable once InconsistentNaming + // ReSharper disable once UnusedParameter.Global + public static TwiMLResult TwiML(this IResultExtensions results, TwiML.TwiML twimlResponse) + => new TwiMLResult(twimlResponse); +} - public static IResult TwiML(this IResultExtensions resultExtensions, VoiceResponse response) - => new TwiMLResult(response); - } +/// +/// Writes TwiML object to the HTTP response body +/// +// ReSharper disable once InconsistentNaming +public class TwiMLResult : IResult +{ + // ReSharper disable once InconsistentNaming + private string twiML; - public class TwiMLResult : IResult + /// + /// Creates a TwiMLResult object + /// + /// The TwiML to write to the HTTP response body + // ReSharper disable once InconsistentNaming + public TwiMLResult(TwiML.TwiML twimlResponse) { - private string twiML; - - public TwiMLResult(MessagingResponse response) - { - twiML = response?.ToString(); - } - - public TwiMLResult(VoiceResponse response) - { - twiML = response?.ToString(); - } + twiML = twimlResponse?.ToString(); + } - public Task ExecuteAsync(HttpContext httpContext) - { - twiML ??= ""; + /// + /// Writes the TwiML to the HTTP response body + /// + /// The HttpContext containing the Response to write the TwiML to + public Task ExecuteAsync(HttpContext httpContext) + { + twiML ??= ""; - httpContext.Response.ContentType = "application/xml"; - httpContext.Response.ContentLength = Encoding.UTF8.GetByteCount(twiML); - return httpContext.Response.WriteAsync(twiML); - } + httpContext.Response.ContentType = "application/xml"; + httpContext.Response.ContentLength = Encoding.UTF8.GetByteCount(twiML); + return httpContext.Response.WriteAsync(twiML); } } + #endif \ No newline at end of file From a19bb6672262a7e7e3f0ca76180aa70798d83725 Mon Sep 17 00:00:00 2001 From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com> Date: Thu, 24 Feb 2022 14:40:16 -0500 Subject: [PATCH 6/7] Add TwilioController tests, make TwilioController methods public --- .../TwilioControllerTests.cs | 53 +++++++++++++++++++ src/Twilio.AspNet.Core/TwilioController.cs | 4 +- 2 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 src/Twilio.AspNet.Core.UnitTests/TwilioControllerTests.cs diff --git a/src/Twilio.AspNet.Core.UnitTests/TwilioControllerTests.cs b/src/Twilio.AspNet.Core.UnitTests/TwilioControllerTests.cs new file mode 100644 index 0000000..fd0aa7a --- /dev/null +++ b/src/Twilio.AspNet.Core.UnitTests/TwilioControllerTests.cs @@ -0,0 +1,53 @@ +using System.IO; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Abstractions; +using Microsoft.AspNetCore.Mvc.ModelBinding; +using Microsoft.AspNetCore.Routing; +using Twilio.TwiML; +using Xunit; + +namespace Twilio.AspNet.Core.UnitTests +{ + public class TwilioControllerTests + { + [Fact] + public async Task TestTwimlResultWritesVoiceResponseToResponseBody() + { + var twiml = new VoiceResponse().Say("Hello World"); + var result = new TwilioController().TwiML(twiml); + var actionContext = CreateActionContext(); + await result.ExecuteResultAsync(actionContext); + + actionContext.HttpContext.Response.Body.Seek(0, SeekOrigin.Begin); + var reader = new StreamReader(actionContext.HttpContext.Response.Body); + var responseBody = await reader.ReadToEndAsync(); + Assert.Equal(twiml.ToString(), responseBody); + } + + [Fact] + public async Task TestTwimlResultWritesMessageResponseToResponseBody() + { + var twiml = new MessagingResponse().Message("Hello World"); + var result = new TwilioController().TwiML(twiml); + var actionContext = CreateActionContext(); + await result.ExecuteResultAsync(actionContext); + + actionContext.HttpContext.Response.Body.Seek(0, SeekOrigin.Begin); + var reader = new StreamReader(actionContext.HttpContext.Response.Body); + var responseBody = await reader.ReadToEndAsync(); + Assert.Equal(twiml.ToString(), responseBody); + } + + private ActionContext CreateActionContext() + { + var httpContext = new DefaultHttpContext(); + httpContext.Response.Body = new MemoryStream(); + return new ActionContext(httpContext, + new RouteData(), + new ActionDescriptor(), + new ModelStateDictionary()); + } + } +} \ No newline at end of file diff --git a/src/Twilio.AspNet.Core/TwilioController.cs b/src/Twilio.AspNet.Core/TwilioController.cs index 47d2f13..0ce7b1b 100644 --- a/src/Twilio.AspNet.Core/TwilioController.cs +++ b/src/Twilio.AspNet.Core/TwilioController.cs @@ -14,7 +14,7 @@ public class TwilioController : ControllerBase /// /// // ReSharper disable once InconsistentNaming - protected TwiMLResult TwiML(MessagingResponse response) + public TwiMLResult TwiML(MessagingResponse response) { return new TwiMLResult(response); } @@ -25,7 +25,7 @@ protected TwiMLResult TwiML(MessagingResponse response) /// /// // ReSharper disable once InconsistentNaming - protected TwiMLResult TwiML(VoiceResponse response) + public TwiMLResult TwiML(VoiceResponse response) { return new TwiMLResult(response); } From 64af4c3b7eb568afd6703a471e1f62492a372415 Mon Sep 17 00:00:00 2001 From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com> Date: Thu, 24 Feb 2022 15:18:04 -0500 Subject: [PATCH 7/7] Remove test apps from solution to not break buils.ps1 --- src/Twilio.AspNet.sln | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/Twilio.AspNet.sln b/src/Twilio.AspNet.sln index 18b6ac9..1517447 100644 --- a/src/Twilio.AspNet.sln +++ b/src/Twilio.AspNet.sln @@ -17,10 +17,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Twilio.AspNet.Core", "Twili EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Twilio.AspNet.Mvc.UnitTests", "Twilio.AspNet.Mvc.UnitTests\Twilio.AspNet.Mvc.UnitTests.csproj", "{B92BDA0D-AD69-4756-BBD6-6E77C4B51906}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testapps", "testapps", "{06967A7D-E066-42D8-8915-5852EA932C6A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnet6", "testapps\dotnet6\dotnet6.csproj", "{131F1920-1002-4BF1-925C-1826F7422F03}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Twilio.AspNet.Core.UnitTests", "Twilio.AspNet.Core.UnitTests\Twilio.AspNet.Core.UnitTests.csproj", "{B3E732C9-27EF-4E96-B620-5B5DA57D9AD3}" EndProject Global @@ -45,10 +41,6 @@ Global {B92BDA0D-AD69-4756-BBD6-6E77C4B51906}.Debug|Any CPU.Build.0 = Debug|Any CPU {B92BDA0D-AD69-4756-BBD6-6E77C4B51906}.Release|Any CPU.ActiveCfg = Release|Any CPU {B92BDA0D-AD69-4756-BBD6-6E77C4B51906}.Release|Any CPU.Build.0 = Release|Any CPU - {131F1920-1002-4BF1-925C-1826F7422F03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {131F1920-1002-4BF1-925C-1826F7422F03}.Debug|Any CPU.Build.0 = Debug|Any CPU - {131F1920-1002-4BF1-925C-1826F7422F03}.Release|Any CPU.ActiveCfg = Release|Any CPU - {131F1920-1002-4BF1-925C-1826F7422F03}.Release|Any CPU.Build.0 = Release|Any CPU {FABCBDFB-E9F8-4B0F-9657-7B156CDA98C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FABCBDFB-E9F8-4B0F-9657-7B156CDA98C2}.Debug|Any CPU.Build.0 = Debug|Any CPU {FABCBDFB-E9F8-4B0F-9657-7B156CDA98C2}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -64,7 +56,4 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {7D0F9171-129A-4B05-809E-F501DBC23197} EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {131F1920-1002-4BF1-925C-1826F7422F03} = {06967A7D-E066-42D8-8915-5852EA932C6A} - EndGlobalSection EndGlobal