Incremental work on tests and QA
This commit is contained in:
parent
6dad26ac3c
commit
bd3b41440a
|
|
@ -10,3 +10,6 @@ indent_size=4
|
|||
resharper_csharp_max_line_length=240
|
||||
resharper_keep_user_linebreaks=true
|
||||
|
||||
# Microsoft .NET properties
|
||||
csharp_new_line_before_members_in_object_initializers=false
|
||||
|
||||
|
|
|
|||
16
Elsa.sln
16
Elsa.sln
|
|
@ -52,9 +52,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Server.Core", "src\ser
|
|||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{AB1AE008-6FD6-414C-8E88-D735F42E1FA6}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "unit", "unit", "{0A3C36AB-2ACF-4175-A512-66B4C3DB9371}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Core.UnitTests", "test\unit\Elsa.Core.UnitTests\Elsa.Core.UnitTests.csproj", "{475EEB95-ED27-4366-88EA-97C5000AC8E8}"
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "integration", "integration", "{0A3C36AB-2ACF-4175-A512-66B4C3DB9371}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{0A6747EA-7AC6-4B6F-BC0C-C40C8A80C44D}"
|
||||
EndProject
|
||||
|
|
@ -72,6 +70,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "locking", "locking", "{7CD5
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.YesSql.Provider.Sqlite.InMemory", "src\core\Elsa.YesSql.Provider.Sqlite.InMemory\Elsa.YesSql.Provider.Sqlite.InMemory.csproj", "{E2D63391-1986-45C8-A18F-4D58F3D71057}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Core.IntegrationTests", "test\integration\Elsa.Core.IntegrationTests\Elsa.Core.IntegrationTests.csproj", "{3C43CC9B-E64F-4481-9B27-3E868AD95CE9}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -130,10 +130,6 @@ Global
|
|||
{D91E2F7B-D5B7-4D1C-A3F0-B0475C33F539}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D91E2F7B-D5B7-4D1C-A3F0-B0475C33F539}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D91E2F7B-D5B7-4D1C-A3F0-B0475C33F539}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{475EEB95-ED27-4366-88EA-97C5000AC8E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{475EEB95-ED27-4366-88EA-97C5000AC8E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{475EEB95-ED27-4366-88EA-97C5000AC8E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{475EEB95-ED27-4366-88EA-97C5000AC8E8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E7C689EB-5AD6-4E91-A007-6116EEA702FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E7C689EB-5AD6-4E91-A007-6116EEA702FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E7C689EB-5AD6-4E91-A007-6116EEA702FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
|
@ -159,6 +155,10 @@ Global
|
|||
{E2D63391-1986-45C8-A18F-4D58F3D71057}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E2D63391-1986-45C8-A18F-4D58F3D71057}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E2D63391-1986-45C8-A18F-4D58F3D71057}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3C43CC9B-E64F-4481-9B27-3E868AD95CE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3C43CC9B-E64F-4481-9B27-3E868AD95CE9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3C43CC9B-E64F-4481-9B27-3E868AD95CE9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3C43CC9B-E64F-4481-9B27-3E868AD95CE9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -182,7 +182,6 @@ Global
|
|||
{468E498C-59DB-4541-8D8A-0D89DE9083AB} = {DA71CDAA-8DD3-4D5F-9FBD-8E4B37A2D925}
|
||||
{D91E2F7B-D5B7-4D1C-A3F0-B0475C33F539} = {468E498C-59DB-4541-8D8A-0D89DE9083AB}
|
||||
{0A3C36AB-2ACF-4175-A512-66B4C3DB9371} = {AB1AE008-6FD6-414C-8E88-D735F42E1FA6}
|
||||
{475EEB95-ED27-4366-88EA-97C5000AC8E8} = {0A3C36AB-2ACF-4175-A512-66B4C3DB9371}
|
||||
{0A6747EA-7AC6-4B6F-BC0C-C40C8A80C44D} = {AB1AE008-6FD6-414C-8E88-D735F42E1FA6}
|
||||
{E7C689EB-5AD6-4E91-A007-6116EEA702FC} = {0A6747EA-7AC6-4B6F-BC0C-C40C8A80C44D}
|
||||
{12D29DDC-A885-4CAA-908C-106D845B10C0} = {468E498C-59DB-4541-8D8A-0D89DE9083AB}
|
||||
|
|
@ -191,6 +190,7 @@ Global
|
|||
{EBD49CCA-5400-4C36-B5DF-7B28190AA323} = {7CD5C8D5-EC78-4A99-A514-F01CA7197AC8}
|
||||
{150EF356-E8BC-4922-91C2-362017479409} = {7CD5C8D5-EC78-4A99-A514-F01CA7197AC8}
|
||||
{E2D63391-1986-45C8-A18F-4D58F3D71057} = {35F44BE9-13D0-417C-A01A-F0787BEE6DC3}
|
||||
{3C43CC9B-E64F-4481-9B27-3E868AD95CE9} = {0A3C36AB-2ACF-4175-A512-66B4C3DB9371}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {8B0975FD-7050-48B0-88C5-48C33378E158}
|
||||
|
|
|
|||
40
Samples.sln
40
Samples.sln
|
|
@ -56,9 +56,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Server.Host", "src\ser
|
|||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{AB1AE008-6FD6-414C-8E88-D735F42E1FA6}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "unit", "unit", "{0A3C36AB-2ACF-4175-A512-66B4C3DB9371}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Core.UnitTests", "test\unit\Elsa.Core.UnitTests\Elsa.Core.UnitTests.csproj", "{475EEB95-ED27-4366-88EA-97C5000AC8E8}"
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "integration", "integration", "{0A3C36AB-2ACF-4175-A512-66B4C3DB9371}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{0A6747EA-7AC6-4B6F-BC0C-C40C8A80C44D}"
|
||||
EndProject
|
||||
|
|
@ -68,8 +66,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Samples.Timers", "src\
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.DistributedLocking.SqlServer", "src\providers\Elsa.DistributedLocking.SqlServer\Elsa.DistributedLocking.SqlServer.csproj", "{150EF356-E8BC-4922-91C2-362017479409}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Server.GraphQL", "src\server\Elsa.Server.GraphQL\Elsa.Server.GraphQL.csproj", "{12D29DDC-A885-4CAA-908C-106D845B10C0}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Samples.Serialization", "src\samples\Elsa.Samples.Serialization\Elsa.Samples.Serialization.csproj", "{DF47517F-9029-44DF-A29F-F2DE15041473}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Samples.HelloWorldConsole", "src\samples\Elsa.Samples.HelloWorldConsole\Elsa.Samples.HelloWorldConsole.csproj", "{E224F8CF-F9F5-4E99-B405-758F3C02C47A}"
|
||||
|
|
@ -94,6 +90,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Samples.ReadLineEchoCo
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.YesSql.Provider.Sqlite.InMemory", "src\core\Elsa.YesSql.Provider.Sqlite.InMemory\Elsa.YesSql.Provider.Sqlite.InMemory.csproj", "{D0364288-3072-44F4-877C-7721C20BC27F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Core.IntegrationTests", "test\integration\Elsa.Core.IntegrationTests\Elsa.Core.IntegrationTests.csproj", "{4CB34AB3-01C9-4911-8914-EABAA744EAD3}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "component", "component", "{FC47A50F-03B2-47D8-AAFB-075314FBA186}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.ComponentTests", "test\component\Elsa.ComponentTests\Elsa.ComponentTests.csproj", "{BB5819C7-434A-4AC5-8B0E-6C4FA672EBD5}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Server.Api", "src\server\Elsa.Server.Api\Elsa.Server.Api.csproj", "{44E0B699-A140-4551-A0E9-9FD9F171A9C2}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -156,10 +160,6 @@ Global
|
|||
{FC54EDBA-71FB-4A87-8FD5-54759DF77CCE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FC54EDBA-71FB-4A87-8FD5-54759DF77CCE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FC54EDBA-71FB-4A87-8FD5-54759DF77CCE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{475EEB95-ED27-4366-88EA-97C5000AC8E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{475EEB95-ED27-4366-88EA-97C5000AC8E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{475EEB95-ED27-4366-88EA-97C5000AC8E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{475EEB95-ED27-4366-88EA-97C5000AC8E8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E7C689EB-5AD6-4E91-A007-6116EEA702FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E7C689EB-5AD6-4E91-A007-6116EEA702FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E7C689EB-5AD6-4E91-A007-6116EEA702FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
|
@ -172,10 +172,6 @@ Global
|
|||
{150EF356-E8BC-4922-91C2-362017479409}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{150EF356-E8BC-4922-91C2-362017479409}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{150EF356-E8BC-4922-91C2-362017479409}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{12D29DDC-A885-4CAA-908C-106D845B10C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{12D29DDC-A885-4CAA-908C-106D845B10C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{12D29DDC-A885-4CAA-908C-106D845B10C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{12D29DDC-A885-4CAA-908C-106D845B10C0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DF47517F-9029-44DF-A29F-F2DE15041473}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DF47517F-9029-44DF-A29F-F2DE15041473}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DF47517F-9029-44DF-A29F-F2DE15041473}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
|
@ -221,6 +217,18 @@ Global
|
|||
{D0364288-3072-44F4-877C-7721C20BC27F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D0364288-3072-44F4-877C-7721C20BC27F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D0364288-3072-44F4-877C-7721C20BC27F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4CB34AB3-01C9-4911-8914-EABAA744EAD3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4CB34AB3-01C9-4911-8914-EABAA744EAD3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4CB34AB3-01C9-4911-8914-EABAA744EAD3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4CB34AB3-01C9-4911-8914-EABAA744EAD3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BB5819C7-434A-4AC5-8B0E-6C4FA672EBD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BB5819C7-434A-4AC5-8B0E-6C4FA672EBD5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BB5819C7-434A-4AC5-8B0E-6C4FA672EBD5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BB5819C7-434A-4AC5-8B0E-6C4FA672EBD5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{44E0B699-A140-4551-A0E9-9FD9F171A9C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{44E0B699-A140-4551-A0E9-9FD9F171A9C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{44E0B699-A140-4551-A0E9-9FD9F171A9C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{44E0B699-A140-4551-A0E9-9FD9F171A9C2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -246,11 +254,9 @@ Global
|
|||
{D91E2F7B-D5B7-4D1C-A3F0-B0475C33F539} = {468E498C-59DB-4541-8D8A-0D89DE9083AB}
|
||||
{FC54EDBA-71FB-4A87-8FD5-54759DF77CCE} = {468E498C-59DB-4541-8D8A-0D89DE9083AB}
|
||||
{0A3C36AB-2ACF-4175-A512-66B4C3DB9371} = {AB1AE008-6FD6-414C-8E88-D735F42E1FA6}
|
||||
{475EEB95-ED27-4366-88EA-97C5000AC8E8} = {0A3C36AB-2ACF-4175-A512-66B4C3DB9371}
|
||||
{0A6747EA-7AC6-4B6F-BC0C-C40C8A80C44D} = {AB1AE008-6FD6-414C-8E88-D735F42E1FA6}
|
||||
{E7C689EB-5AD6-4E91-A007-6116EEA702FC} = {0A6747EA-7AC6-4B6F-BC0C-C40C8A80C44D}
|
||||
{071DD6EC-D00C-4513-82B6-3FE8438061E3} = {5E5E1E84-DDBC-40D6-B891-0D563A15A44A}
|
||||
{12D29DDC-A885-4CAA-908C-106D845B10C0} = {468E498C-59DB-4541-8D8A-0D89DE9083AB}
|
||||
{DF47517F-9029-44DF-A29F-F2DE15041473} = {5E5E1E84-DDBC-40D6-B891-0D563A15A44A}
|
||||
{E224F8CF-F9F5-4E99-B405-758F3C02C47A} = {5E5E1E84-DDBC-40D6-B891-0D563A15A44A}
|
||||
{A11D79AE-F4C9-4595-9B73-0E0AB221B90D} = {5E5E1E84-DDBC-40D6-B891-0D563A15A44A}
|
||||
|
|
@ -264,6 +270,10 @@ Global
|
|||
{F755FB1F-72FB-4F7B-8270-F5F40F4D6952} = {5E5E1E84-DDBC-40D6-B891-0D563A15A44A}
|
||||
{867CB845-B803-4D40-9360-3D11ADBD9CE9} = {5E5E1E84-DDBC-40D6-B891-0D563A15A44A}
|
||||
{D0364288-3072-44F4-877C-7721C20BC27F} = {35F44BE9-13D0-417C-A01A-F0787BEE6DC3}
|
||||
{4CB34AB3-01C9-4911-8914-EABAA744EAD3} = {0A3C36AB-2ACF-4175-A512-66B4C3DB9371}
|
||||
{FC47A50F-03B2-47D8-AAFB-075314FBA186} = {AB1AE008-6FD6-414C-8E88-D735F42E1FA6}
|
||||
{BB5819C7-434A-4AC5-8B0E-6C4FA672EBD5} = {FC47A50F-03B2-47D8-AAFB-075314FBA186}
|
||||
{44E0B699-A140-4551-A0E9-9FD9F171A9C2} = {468E498C-59DB-4541-8D8A-0D89DE9083AB}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {8B0975FD-7050-48B0-88C5-48C33378E158}
|
||||
|
|
|
|||
|
|
@ -8,4 +8,5 @@
|
|||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Configurer/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Configurer/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Noda/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
|
|
@ -22,7 +22,7 @@ namespace Elsa.Activities.Console
|
|||
)]
|
||||
public class ReadLine : Activity
|
||||
{
|
||||
private readonly TextReader _input;
|
||||
private readonly TextReader? _input;
|
||||
|
||||
public ReadLine()
|
||||
{
|
||||
|
|
@ -46,7 +46,7 @@ namespace Elsa.Activities.Console
|
|||
|
||||
protected override IActivityExecutionResult OnResume(ActivityExecutionContext context)
|
||||
{
|
||||
var receivedInput = (string)context.Input;
|
||||
var receivedInput = (string)context.Input!;
|
||||
return Execute(receivedInput);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ namespace Elsa.Activities.Console
|
|||
}
|
||||
|
||||
[ActivityProperty(Hint = "The text to write.")]
|
||||
public string Text { get; set; }
|
||||
public string? Text { get; set; }
|
||||
|
||||
private readonly TextWriter _output;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Builders;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace Elsa.Activities.Console
|
||||
{
|
||||
public static class WriteLineExtensions
|
||||
{
|
||||
public static ISetupActivity<WriteLine> WithText(this ISetupActivity<WriteLine> writeLine, Func<ActivityExecutionContext, ValueTask<string?>> text) => writeLine.Set(x => x.Text, text);
|
||||
public static ISetupActivity<WriteLine> WithText(this ISetupActivity<WriteLine> writeLine, Func<ActivityExecutionContext, string> text) => writeLine.Set(x => x.Text, text);
|
||||
public static ISetupActivity<WriteLine> WithText(this ISetupActivity<WriteLine> writeLine, Func<ValueTask<string?>> text) => writeLine.Set(x => x.Text, text);
|
||||
public static ISetupActivity<WriteLine> WithText(this ISetupActivity<WriteLine> writeLine, Func<string?> text) => writeLine.Set(x => x.Text, text);
|
||||
public static ISetupActivity<WriteLine> WithText(this ISetupActivity<WriteLine> writeLine, string? text) => writeLine.Set(x => x.Text, text);
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@
|
|||
<RepositoryType>GitHub</RepositoryType>
|
||||
<PackageTags>elsa, workflows</PackageTags>
|
||||
<PackageIcon>icon.png</PackageIcon>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -7,10 +7,11 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
{
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddConsoleActivities(this IServiceCollection services, TextReader standardIn = default)
|
||||
public static IServiceCollection AddConsoleActivities(this IServiceCollection services, TextReader? standardIn = default, TextWriter? standardOut = default)
|
||||
{
|
||||
return services
|
||||
.AddSingleton(standardIn ?? Console.In)
|
||||
.AddSingleton(standardOut ?? Console.Out)
|
||||
.AddActivity<ReadLine>()
|
||||
.AddActivity<WriteLine>();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="3.1.7" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="3.1.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="3.1.9" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ namespace Elsa.Activities.UserTask.Activities
|
|||
)]
|
||||
public class UserTask : Activity
|
||||
{
|
||||
private readonly IJsonSerializer _serializer;
|
||||
private readonly IContentSerializer _serializer;
|
||||
|
||||
[ActivityProperty(
|
||||
Type = ActivityPropertyTypes.List,
|
||||
|
|
@ -28,7 +28,7 @@ namespace Elsa.Activities.UserTask.Activities
|
|||
)]
|
||||
public ICollection<string> Actions { get; set; } = new List<string>();
|
||||
|
||||
public UserTask(IJsonSerializer serializer)
|
||||
public UserTask(IContentSerializer serializer)
|
||||
{
|
||||
_serializer = serializer;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="3.1.7" />
|
||||
<PackageReference Include="Microsoft.Extensions.Primitives" Version="3.1.7" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.9" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="3.1.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.Primitives" Version="3.1.8" />
|
||||
<PackageReference Include="NodaTime" Version="3.0.2" />
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace Elsa
|
|||
{
|
||||
public static class VariablesExtensions
|
||||
{
|
||||
public static T Get<T>(this Variables variables, string name, IJsonSerializer serializer)
|
||||
public static T Get<T>(this Variables variables, string name, IContentSerializer serializer)
|
||||
{
|
||||
var value = variables.Get(name);
|
||||
return value != null ? serializer.Deserialize<T>(value) : default!;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,21 @@ namespace Elsa.Models
|
|||
{
|
||||
public class ActivityDefinitionPropertyValue
|
||||
{
|
||||
public static ActivityDefinitionPropertyValue Literal<T>(T value) => new ActivityDefinitionPropertyValue(value!.ToString(), "Literal", typeof(T));
|
||||
public static ActivityDefinitionPropertyValue Liquid<T>(string expression) => new ActivityDefinitionPropertyValue(expression, "Liquid", typeof(T));
|
||||
public static ActivityDefinitionPropertyValue JavaScript<T>(string expression) => new ActivityDefinitionPropertyValue(expression, "JavaScript", typeof(T));
|
||||
|
||||
public ActivityDefinitionPropertyValue()
|
||||
{
|
||||
}
|
||||
|
||||
public ActivityDefinitionPropertyValue(string expression, string syntax, Type type)
|
||||
{
|
||||
Expression = expression;
|
||||
Syntax = syntax;
|
||||
Type = type;
|
||||
}
|
||||
|
||||
public Type Type { get; set; } = default!;
|
||||
public string Syntax { get; set; } = default!;
|
||||
public string Expression { get; set; } = default!;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Elsa.Serialization
|
||||
{
|
||||
public interface IJsonSerializer
|
||||
public interface IContentSerializer
|
||||
{
|
||||
JObject Serialize<T>(T value);
|
||||
T Deserialize<T>(JToken token);
|
||||
|
|
@ -13,7 +13,7 @@ namespace Elsa.Services
|
|||
string? activityId = default,
|
||||
object? input = default,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
|
||||
ValueTask<WorkflowInstance> RunWorkflowAsync(
|
||||
IWorkflowBlueprint workflowDefinition,
|
||||
WorkflowInstance workflowInstance,
|
||||
|
|
@ -27,17 +27,32 @@ namespace Elsa.Services
|
|||
object? input = default,
|
||||
string? correlationId = default,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
|
||||
ValueTask<WorkflowInstance> RunWorkflowAsync<T>(
|
||||
string? activityId = default,
|
||||
object? input = default,
|
||||
string? correlationId = default,
|
||||
CancellationToken cancellationToken = default) where T:IWorkflow;
|
||||
|
||||
CancellationToken cancellationToken = default) where T : IWorkflow;
|
||||
|
||||
ValueTask<WorkflowInstance> RunWorkflowAsync<T>(
|
||||
WorkflowInstance workflowInstance,
|
||||
string? activityId = default,
|
||||
object? input = default,
|
||||
CancellationToken cancellationToken = default) where T:IWorkflow;
|
||||
CancellationToken cancellationToken = default) where T : IWorkflow;
|
||||
|
||||
ValueTask<WorkflowInstance> RunWorkflowAsync(
|
||||
IWorkflow workflow,
|
||||
string? activityId = default,
|
||||
object? input = default,
|
||||
string? correlationId = default,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
ValueTask<WorkflowInstance> RunWorkflowAsync(
|
||||
IWorkflow workflow,
|
||||
WorkflowInstance workflowInstance,
|
||||
string? activityId = default,
|
||||
object? input = default,
|
||||
string? correlationId = default,
|
||||
CancellationToken cancellationToken = default);
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,6 @@ namespace Elsa.Services.Models
|
|||
ServiceProvider = serviceProvider;
|
||||
WorkflowBlueprint = workflowBlueprint;
|
||||
WorkflowInstance = workflowInstance;
|
||||
ExecutionLog = new List<ExecutionLogEntry>(workflowInstance.ExecutionLog);
|
||||
IsFirstPass = true;
|
||||
}
|
||||
|
||||
|
|
@ -47,7 +46,7 @@ namespace Elsa.Services.Models
|
|||
public ScheduledActivity PeekScheduledActivity() => WorkflowInstance.ScheduledActivities.Peek();
|
||||
public string? CorrelationId { get; set; }
|
||||
public bool DeleteCompletedInstances { get; set; }
|
||||
public ICollection<ExecutionLogEntry> ExecutionLog { get; }
|
||||
public ICollection<ExecutionLogEntry> ExecutionLog => WorkflowInstance.ExecutionLog;
|
||||
public WorkflowStatus Status => WorkflowInstance.Status;
|
||||
|
||||
public void SetVariable(string name, object? value) => WorkflowInstance.Variables.Set(name, JToken.FromObject(value!));
|
||||
|
|
|
|||
|
|
@ -93,11 +93,9 @@ namespace Elsa.Builders
|
|||
|
||||
public IActivityBuilder New(
|
||||
Type activityType,
|
||||
Action<IActivityBuilder>? branch = default,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default)
|
||||
{
|
||||
var activityBuilder = new ActivityBuilder(activityType, this, propertyValueProviders);
|
||||
branch?.Invoke(activityBuilder);
|
||||
return activityBuilder;
|
||||
}
|
||||
|
||||
|
|
@ -105,7 +103,7 @@ namespace Elsa.Builders
|
|||
Action<IActivityBuilder>? branch = default,
|
||||
IDictionary<string, IActivityPropertyValueProvider>? propertyValueProviders = default)
|
||||
where T : class, IActivity =>
|
||||
New(typeof(T), branch, propertyValueProviders);
|
||||
New(typeof(T), propertyValueProviders);
|
||||
|
||||
public IActivityBuilder New<T>(
|
||||
Action<ISetupActivity<T>>? setup = default,
|
||||
|
|
|
|||
|
|
@ -5,14 +5,14 @@ using Elsa.Queries;
|
|||
using Elsa.Services;
|
||||
using Rebus.Handlers;
|
||||
|
||||
namespace Elsa.Messaging.Distributed.Handlers
|
||||
namespace Elsa.Consumers
|
||||
{
|
||||
public class RunWorkflowHandler : IHandleMessages<RunWorkflow>
|
||||
public class RunWorkflowConsumer : IHandleMessages<RunWorkflow>
|
||||
{
|
||||
private readonly IWorkflowHost _workflowHost;
|
||||
private readonly IWorkflowInstanceManager _workflowInstanceManager;
|
||||
|
||||
public RunWorkflowHandler(IWorkflowHost workflowHost, IWorkflowInstanceManager workflowInstanceManager)
|
||||
public RunWorkflowConsumer(IWorkflowHost workflowHost, IWorkflowInstanceManager workflowInstanceManager)
|
||||
{
|
||||
_workflowHost = workflowHost;
|
||||
_workflowInstanceManager = workflowInstanceManager;
|
||||
|
|
@ -46,7 +46,7 @@
|
|||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.1.7" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="3.1.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="3.1.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.9" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="3.1.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="3.1.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.8" />
|
||||
|
|
@ -69,7 +69,6 @@
|
|||
|
||||
<ItemGroup>
|
||||
<Folder Include="Data" />
|
||||
<Folder Include="Messaging\Domain" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -29,7 +29,7 @@ namespace Elsa
|
|||
|
||||
CreateJsonSerializer = sp =>
|
||||
{
|
||||
var serializer = DefaultJsonSerializer.CreateDefaultJsonSerializer();
|
||||
var serializer = ContentSerializer.CreateDefaultJsonSerializer();
|
||||
JsonSerializerConfigurer(sp, serializer);
|
||||
return serializer;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Elsa.Services;
|
||||
|
||||
namespace Elsa.Extensions
|
||||
{
|
||||
public static class ActivityCollectionExtensions
|
||||
{
|
||||
public static IEnumerable<IActivity> Find(this IEnumerable<IActivity> collection, IEnumerable<string> ids)
|
||||
{
|
||||
var idList = ids?.ToList();
|
||||
return idList != null ? collection.Where(x => idList.Contains(x.Id)) : default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +1,26 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Elsa;
|
||||
using Elsa.Activities.ControlFlow;
|
||||
using Elsa.Activities.Primitives;
|
||||
using Elsa.Activities.Signaling;
|
||||
using Elsa.Builders;
|
||||
using Elsa.Consumers;
|
||||
using Elsa.Converters;
|
||||
using Elsa.Data;
|
||||
using Elsa.Data.Extensions;
|
||||
using Elsa.Events;
|
||||
using Elsa.Expressions;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Handlers;
|
||||
using Elsa.Indexes;
|
||||
using Elsa.Messages;
|
||||
using Elsa.Messaging;
|
||||
using Elsa.Messaging.Distributed.Handlers;
|
||||
using Elsa.Metadata;
|
||||
using Elsa.Metadata.Handlers;
|
||||
using Elsa.Runtime;
|
||||
using Elsa.Serialization;
|
||||
using Elsa.ServiceBus;
|
||||
using Elsa.Services;
|
||||
using Elsa.StartupTasks;
|
||||
using Elsa.Triggers;
|
||||
|
|
@ -67,13 +71,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
}
|
||||
|
||||
public static IServiceCollection AddConsumer<TMessage, TConsumer>(this IServiceCollection services) where TConsumer : class, IHandleMessages<TMessage> => services.AddTransient<IHandleMessages<TMessage>, TConsumer>();
|
||||
|
||||
private static IServiceCollection AddMediatR(this ElsaOptions options)
|
||||
{
|
||||
return options.Services.AddMediatR(
|
||||
mediatr => mediatr.AsScoped(),
|
||||
typeof(ElsaServiceCollectionExtensions));
|
||||
}
|
||||
private static IServiceCollection AddMediatR(this ElsaOptions options) => options.Services.AddMediatR(mediatr => mediatr.AsScoped(), typeof(IActivity));
|
||||
|
||||
private static ElsaOptions AddWorkflowsCore(this ElsaOptions configuration)
|
||||
{
|
||||
|
|
@ -87,7 +85,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
.AddTransient<Func<IEnumerable<IActivity>>>(sp => sp.GetServices<IActivity>)
|
||||
.AddSingleton<IIdGenerator, IdGenerator>()
|
||||
.AddSingleton(sp => sp.GetRequiredService<ElsaOptions>().CreateJsonSerializer(sp))
|
||||
.AddSingleton<IJsonSerializer, DefaultJsonSerializer>()
|
||||
.AddSingleton<IContentSerializer, ContentSerializer>()
|
||||
.AddSingleton<IActivitySerializer, ActivitySerializer>()
|
||||
.AddSingleton<TypeConverter>()
|
||||
.TryAddProvider<IExpressionHandler, LiteralHandler>(ServiceLifetime.Singleton)
|
||||
|
|
@ -99,7 +97,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
.AddScoped<IWorkflowHost, WorkflowHost>()
|
||||
.AddSingleton<IWorkflowFactory, WorkflowFactory>()
|
||||
.AddSingleton<IWorkflowBlueprintMaterializer, WorkflowBlueprintMaterializer>()
|
||||
.AddSingleton<IWorkflowSelector, WorkflowSelector>()
|
||||
.AddScoped<IWorkflowSelector, WorkflowSelector>()
|
||||
.AddScoped<IWorkflowDefinitionManager, WorkflowDefinitionManager>()
|
||||
.AddScoped<IWorkflowInstanceManager, WorkflowInstanceManager>()
|
||||
.AddIndexProvider<WorkflowDefinitionIndexProvider>()
|
||||
|
|
@ -109,8 +107,9 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
.AddWorkflowProvider<CodeWorkflowProvider>()
|
||||
.AddTransient<IWorkflowBuilder, WorkflowBuilder>()
|
||||
.AddTransient<Func<IWorkflowBuilder>>(sp => sp.GetRequiredService<IWorkflowBuilder>)
|
||||
.AddNotificationHandlers(typeof(ElsaServiceCollectionExtensions))
|
||||
.AddStartupTask<StartServiceBusTask>()
|
||||
.AddConsumer<RunWorkflow, RunWorkflowHandler>()
|
||||
.AddConsumer<RunWorkflow, RunWorkflowConsumer>()
|
||||
.AddMetadataHandlers()
|
||||
.AddPrimitiveActivities();
|
||||
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@ using Elsa.Models;
|
|||
using MediatR;
|
||||
using NodaTime;
|
||||
|
||||
namespace Elsa.Messaging.Domain.Handlers
|
||||
namespace Elsa.Handlers
|
||||
{
|
||||
public class WorkflowExecutionLogEventHandler : INotificationHandler<ActivityExecuted>
|
||||
public class AppendExecutionLog : INotificationHandler<ActivityExecuted>
|
||||
{
|
||||
private readonly IClock _clock;
|
||||
public WorkflowExecutionLogEventHandler(IClock clock) => _clock = clock;
|
||||
public AppendExecutionLog(IClock clock) => _clock = clock;
|
||||
|
||||
public Task Handle(ActivityExecuted notification, CancellationToken cancellationToken)
|
||||
{
|
||||
|
|
@ -7,9 +7,9 @@ using Elsa.Services.Models;
|
|||
using MediatR;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Elsa.Messaging.Domain.Handlers
|
||||
namespace Elsa.Handlers
|
||||
{
|
||||
public class PersistenceWorkflowEventHandler :
|
||||
public class PersistWorkflow :
|
||||
INotificationHandler<WorkflowExecuted>,
|
||||
INotificationHandler<WorkflowSuspended>,
|
||||
INotificationHandler<ActivityExecuted>,
|
||||
|
|
@ -18,9 +18,9 @@ namespace Elsa.Messaging.Domain.Handlers
|
|||
private readonly IWorkflowInstanceManager _workflowInstanceManager;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public PersistenceWorkflowEventHandler(
|
||||
public PersistWorkflow(
|
||||
IWorkflowInstanceManager workflowInstanceManager,
|
||||
ILogger<PersistenceWorkflowEventHandler> logger)
|
||||
ILogger<PersistWorkflow> logger)
|
||||
{
|
||||
_workflowInstanceManager = workflowInstanceManager;
|
||||
_logger = logger;
|
||||
|
|
@ -5,8 +5,8 @@ namespace Elsa.Serialization
|
|||
{
|
||||
public class ActivitySerializer : IActivitySerializer
|
||||
{
|
||||
private readonly IJsonSerializer _ijSerializer;
|
||||
public ActivitySerializer(IJsonSerializer ijSerializer) => _ijSerializer = ijSerializer;
|
||||
private readonly IContentSerializer _ijSerializer;
|
||||
public ActivitySerializer(IContentSerializer ijSerializer) => _ijSerializer = ijSerializer;
|
||||
public JObject Serialize<T>(T activity) where T : IActivity => _ijSerializer.Serialize(activity);
|
||||
public T Deserialize<T>(JObject data) where T : IActivity => _ijSerializer.Deserialize<T>(data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ using NodaTime.Serialization.JsonNet;
|
|||
|
||||
namespace Elsa.Serialization
|
||||
{
|
||||
public class DefaultJsonSerializer : IJsonSerializer
|
||||
public class ContentSerializer : IContentSerializer
|
||||
{
|
||||
public DefaultJsonSerializer(JsonSerializer serializer)
|
||||
public ContentSerializer(JsonSerializer serializer)
|
||||
{
|
||||
Serializer = serializer;
|
||||
}
|
||||
|
|
@ -30,9 +30,9 @@ namespace Elsa.Serialization
|
|||
jsonSerializer.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
|
||||
jsonSerializer.NullValueHandling = NullValueHandling.Ignore;
|
||||
jsonSerializer.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
|
||||
jsonSerializer.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
|
||||
jsonSerializer.PreserveReferencesHandling = PreserveReferencesHandling.All;
|
||||
jsonSerializer.TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple;
|
||||
jsonSerializer.TypeNameHandling = TypeNameHandling.Objects;
|
||||
jsonSerializer.TypeNameHandling = TypeNameHandling.None;
|
||||
jsonSerializer.ContractResolver = new CamelCasePropertyNamesContractResolver
|
||||
{
|
||||
NamingStrategy = new CamelCaseNamingStrategy
|
||||
|
|
@ -3,7 +3,7 @@ using Microsoft.Extensions.DependencyInjection;
|
|||
using Rebus.Config;
|
||||
using Rebus.ServiceProvider;
|
||||
|
||||
namespace Elsa.Messaging
|
||||
namespace Elsa.ServiceBus
|
||||
{
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
|
|
@ -27,7 +27,6 @@ namespace Elsa.Services
|
|||
private readonly IWorkflowBuilder _workflowBuilder;
|
||||
private readonly IMediator _mediator;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IEnumerable<ITriggerProvider> _triggerProviders;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public WorkflowHost(
|
||||
|
|
@ -36,7 +35,6 @@ namespace Elsa.Services
|
|||
IWorkflowBuilder workflowBuilder,
|
||||
IMediator mediator,
|
||||
IServiceProvider serviceProvider,
|
||||
IEnumerable<ITriggerProvider> triggerProviders,
|
||||
ILogger<WorkflowHost> logger)
|
||||
{
|
||||
_workflowRegistry = workflowRegistry;
|
||||
|
|
@ -44,7 +42,6 @@ namespace Elsa.Services
|
|||
_workflowBuilder = workflowBuilder;
|
||||
_mediator = mediator;
|
||||
_serviceProvider = serviceProvider;
|
||||
_triggerProviders = triggerProviders;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
|
@ -79,6 +76,29 @@ namespace Elsa.Services
|
|||
where T : IWorkflow =>
|
||||
await RunWorkflowAsync(_workflowBuilder.Build<T>(), workflowInstance, activityId, input, cancellationToken);
|
||||
|
||||
public async ValueTask<WorkflowInstance> RunWorkflowAsync(
|
||||
IWorkflow workflow,
|
||||
string? activityId = default,
|
||||
object? input = default,
|
||||
string? correlationId = default,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var workflowBlueprint = _workflowBuilder.Build(workflow);
|
||||
return await RunWorkflowAsync(workflowBlueprint, activityId, input, correlationId, cancellationToken);
|
||||
}
|
||||
|
||||
public async ValueTask<WorkflowInstance> RunWorkflowAsync(
|
||||
IWorkflow workflow,
|
||||
WorkflowInstance workflowInstance,
|
||||
string? activityId = default,
|
||||
object? input = default,
|
||||
string? correlationId = default,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var workflowBlueprint = _workflowBuilder.Build(workflow);
|
||||
return await RunWorkflowAsync(workflowBlueprint, workflowInstance, activityId, input, cancellationToken);
|
||||
}
|
||||
|
||||
public async ValueTask<WorkflowInstance> RunWorkflowAsync(
|
||||
WorkflowInstance workflowInstance,
|
||||
string? activityId = default,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:62840/",
|
||||
"sslPort": 44305
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"Elsa.Samples.CustomActivities": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "https://localhost:5001;http://localhost:5000"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:62841/",
|
||||
"sslPort": 44336
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"Elsa.Samples.HelloWorldHttp": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "https://localhost:5001;http://localhost:5000"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -60,7 +60,7 @@ namespace Elsa.Samples.Serialization
|
|||
};
|
||||
|
||||
// Serialize workflow definition to JSON.
|
||||
var serializer = services.GetRequiredService<IJsonSerializer>();
|
||||
var serializer = services.GetRequiredService<IContentSerializer>();
|
||||
var json = serializer.Serialize(workflowDefinition);
|
||||
|
||||
Console.WriteLine(json);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.7" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.9" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
29
src/server/Elsa.Server.Api/Elsa.Server.Api.csproj
Normal file
29
src/server/Elsa.Server.Api/Elsa.Server.Api.csproj
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Elsa.Server.Core\Elsa.Server.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="4.1.1" />
|
||||
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.0.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="5.6.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Endpoints\WorkflowDefinitions\Post.Request.cs">
|
||||
<DependentUpon>Post.cs</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Models;
|
||||
using Elsa.Queries;
|
||||
using Elsa.Services;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Elsa.Server.Api.Endpoints.WorkflowDefinitions
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1")]
|
||||
[Route("v{version:apiVersion}/workflow-definitions/{id}")]
|
||||
public class Get : ControllerBase
|
||||
{
|
||||
private readonly IWorkflowDefinitionManager _workflowDefinitionManager;
|
||||
public Get(IWorkflowDefinitionManager workflowDefinitionManager) => _workflowDefinitionManager = workflowDefinitionManager;
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> Handle([FromRoute(Name = "id")] string workflowDefinitionId, CancellationToken cancellationToken)
|
||||
{
|
||||
var workflowDefinition = await _workflowDefinitionManager.GetAsync(workflowDefinitionId, VersionOptions.Latest, cancellationToken);
|
||||
return workflowDefinition == null ? (IActionResult)NotFound() : Ok(workflowDefinition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
using System.Collections.Generic;
|
||||
using Elsa.Models;
|
||||
|
||||
namespace Elsa.Server.Api.Endpoints.WorkflowDefinitions
|
||||
{
|
||||
public class CreateWorkflowDefinitionRequest
|
||||
{
|
||||
public string WorkflowDefinitionId { get; set; } = default!;
|
||||
public string? Name { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public Variables? Variables { get; set; }
|
||||
public bool IsSingleton { get; set; }
|
||||
public WorkflowPersistenceBehavior PersistenceBehavior { get; set; }
|
||||
public bool DeleteCompletedInstances { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
public bool Publish { get; set; }
|
||||
public ICollection<ActivityDefinition> Activities { get; set; } = new List<ActivityDefinition>();
|
||||
public ICollection<ConnectionDefinition> Connections { get; set; } = new List<ConnectionDefinition>();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Models;
|
||||
using Elsa.Services;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Elsa.Server.Api.Endpoints.WorkflowDefinitions
|
||||
{
|
||||
[ApiController]
|
||||
[ApiVersion("1")]
|
||||
[Route("v{version:apiVersion}/workflow-definitions")]
|
||||
public class Post : ControllerBase
|
||||
{
|
||||
private readonly IWorkflowDefinitionManager _workflowDefinitionManager;
|
||||
|
||||
public Post(IWorkflowDefinitionManager workflowDefinitionManager)
|
||||
{
|
||||
_workflowDefinitionManager = workflowDefinitionManager;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> Handle(CreateWorkflowDefinitionRequest request, ApiVersion apiVersion, CancellationToken cancellationToken)
|
||||
{
|
||||
var workflowDefinition = new WorkflowDefinition
|
||||
{
|
||||
WorkflowDefinitionId = request.WorkflowDefinitionId.Trim(),
|
||||
Activities = request.Activities,
|
||||
Connections = request.Connections,
|
||||
Description = request.Description?.Trim(),
|
||||
Name = request.Name?.Trim(),
|
||||
Variables = request.Variables,
|
||||
IsEnabled = request.Enabled,
|
||||
IsLatest = true,
|
||||
IsPublished = request.Publish,
|
||||
Version = 1,
|
||||
IsSingleton = request.IsSingleton,
|
||||
PersistenceBehavior = request.PersistenceBehavior,
|
||||
DeleteCompletedInstances = request.DeleteCompletedInstances
|
||||
};
|
||||
|
||||
await _workflowDefinitionManager.SaveAsync(workflowDefinition, cancellationToken);
|
||||
return CreatedAtAction("Handle", "Get", new { version = apiVersion.ToString() }, workflowDefinition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
using System.Text.Json;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using NodaTime;
|
||||
using NodaTime.Serialization.SystemTextJson;
|
||||
|
||||
namespace Elsa.Server.Api.Extensions
|
||||
{
|
||||
public static class JsonMvcBuilderExtensions
|
||||
{
|
||||
public static IMvcBuilder AddJsonSerialization(this IMvcBuilder builder) =>
|
||||
builder.AddJsonOptions(
|
||||
options =>
|
||||
{
|
||||
options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
|
||||
options.JsonSerializerOptions.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
using Elsa.Server.Api.Extensions;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddElsaApiEndpoints(this IServiceCollection services)
|
||||
{
|
||||
services.AddControllers().SetCompatibilityVersion(CompatibilityVersion.Latest).AddJsonSerialization();
|
||||
services.AddRouting(options => options.LowercaseUrls = true);
|
||||
|
||||
services.AddApiVersioning(
|
||||
options =>
|
||||
{
|
||||
options.ReportApiVersions = true;
|
||||
options.DefaultApiVersion = ApiVersion.Default;
|
||||
options.AssumeDefaultVersionWhenUnspecified = true;
|
||||
});
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,8 @@ using Elsa.Services;
|
|||
using HotChocolate;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Elsa.Server.GraphQL.Extensions
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ namespace Elsa.Server.GraphQL
|
|||
WorkflowInput workflowInput,
|
||||
[Service] IWorkflowDefinitionManager manager,
|
||||
[Service] IIdGenerator idGenerator,
|
||||
[Service] IJsonSerializer serializer,
|
||||
[Service] IContentSerializer serializer,
|
||||
[Service] IWorkflowPublisher publisher,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,14 +5,11 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Elsa.Server.Api\Elsa.Server.Api.csproj" />
|
||||
<ProjectReference Include="..\Elsa.Server.Core\Elsa.Server.Core.csproj" />
|
||||
<ProjectReference Include="..\Elsa.Server.GraphQL\Elsa.Server.GraphQL.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="GraphQL.Server.Ui.GraphiQL" Version="4.0.1" />
|
||||
<PackageReference Include="GraphQL.Server.Ui.Playground" Version="4.0.1" />
|
||||
<PackageReference Include="GraphQL.Server.Ui.Voyager" Version="4.0.1" />
|
||||
<PackageReference Include="YesSql.Provider.Sqlite" Version="1.0.0-beta-1547" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
using Elsa.Runtime;
|
||||
using Elsa.Server.GraphQL.Extensions;
|
||||
using Elsa.StartupTasks;
|
||||
using HotChocolate.AspNetCore;
|
||||
using HotChocolate.AspNetCore.Voyager;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
|
@ -34,7 +31,7 @@ namespace Elsa.Server.Host
|
|||
|
||||
services
|
||||
.AddElsaServer()
|
||||
.AddElsaGraphQL()
|
||||
.AddElsaApiEndpoints()
|
||||
|
||||
.AddCors(options => options.AddDefaultPolicy(cors => cors
|
||||
.AllowAnyOrigin()
|
||||
|
|
@ -57,9 +54,6 @@ namespace Elsa.Server.Host
|
|||
|
||||
app
|
||||
.UseCors()
|
||||
.UseGraphQL("/graphql")
|
||||
.UsePlayground("/graphql")
|
||||
.UseVoyager("/graphql")
|
||||
.UseHttpActivities();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"$id": "1",
|
||||
"workflowDefinitionId": "SampleWorkflow",
|
||||
"workflowDefinitionVersionId": "1",
|
||||
"version": 1,
|
||||
"variables": {
|
||||
"$id": "2",
|
||||
"data": {}
|
||||
},
|
||||
"isEnabled": true,
|
||||
"isPublished": true,
|
||||
"isLatest": true,
|
||||
"activities": {
|
||||
"$id": "3",
|
||||
"$values": [
|
||||
{
|
||||
"$id": "4",
|
||||
"id": "activity-1",
|
||||
"type": "WriteLine",
|
||||
"properties": {
|
||||
"$id": "5",
|
||||
"Text": {
|
||||
"$id": "6",
|
||||
"type": "System.String, mscorlib",
|
||||
"syntax": "Liquid",
|
||||
"expression": "Hello World!"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"connections": {
|
||||
"$id": "7",
|
||||
"$values": []
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoFixture" Version="4.14.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="3.1.9" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="coverlet.collector" Version="1.3.0">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\src\server\Elsa.Server.Host\Elsa.Server.Host.csproj" />
|
||||
<ProjectReference Include="..\..\shared\Elsa.Testing.Shared\Elsa.Testing.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Assets" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Assets\hello-world-workflow.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using AutoFixture;
|
||||
using Elsa.Activities.Console;
|
||||
using Elsa.ComponentTests.Helpers;
|
||||
using Elsa.Core.IntegrationTests.Helpers;
|
||||
using Elsa.Models;
|
||||
using Elsa.Server.Api.Endpoints.WorkflowDefinitions;
|
||||
using Elsa.Testing.Shared.AutoFixture;
|
||||
using Xunit;
|
||||
|
||||
namespace Elsa.ComponentTests.Endpoints.WorkflowDefinitions
|
||||
{
|
||||
[Collection(ComponentTestsCollection.Name)]
|
||||
public class PostTests : IDisposable
|
||||
{
|
||||
private readonly IFixture _fixture;
|
||||
private readonly TemporaryFolder _tempFolder;
|
||||
private readonly ElsaHostApplicationFactory _hostApplicationFactory;
|
||||
private readonly HttpClient _httpClient;
|
||||
|
||||
public PostTests(ElsaHostApplicationFactory hostApplicationFactory)
|
||||
{
|
||||
_fixture = new Fixture().Customize(new NodaTimeCustomization());
|
||||
_tempFolder = new TemporaryFolder();
|
||||
_hostApplicationFactory = hostApplicationFactory;
|
||||
hostApplicationFactory.SetDbConnectionString($@"Data Source={_tempFolder.Folder}elsa.db;Cache=Shared");
|
||||
_httpClient = hostApplicationFactory.CreateClient();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Posting a new workflow definition returns HTTP 201.")]
|
||||
public async Task Post01()
|
||||
{
|
||||
var request = CreateWorkflowDefinitionRequest();
|
||||
var response = await _httpClient.PostJsonAsync("/v1/workflow-definitions", request);
|
||||
|
||||
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
|
||||
}
|
||||
|
||||
private CreateWorkflowDefinitionRequest CreateWorkflowDefinitionRequest()
|
||||
{
|
||||
var writeLine = new ActivityDefinition
|
||||
{
|
||||
Id = _fixture.Create<string>(),
|
||||
Type = nameof(WriteLine),
|
||||
Properties = new ActivityDefinitionProperties
|
||||
{
|
||||
[nameof(WriteLine.Text)] = ActivityDefinitionPropertyValue.Literal("Hello World!")
|
||||
}
|
||||
};
|
||||
|
||||
var readLine = new ActivityDefinition { Id = _fixture.Create<string>(), Type = nameof(ReadLine) };
|
||||
var activities = new[] { writeLine, readLine };
|
||||
var connections = new[] { new ConnectionDefinition(writeLine.Id, readLine.Id, OutcomeNames.Done) };
|
||||
|
||||
return _fixture.Build<CreateWorkflowDefinitionRequest>()
|
||||
.With(x => x.Activities, activities)
|
||||
.With(x => x.Connections, connections)
|
||||
.Create();
|
||||
}
|
||||
|
||||
private string CreateWorkflowDefinitionJson()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_hostApplicationFactory.Dispose();
|
||||
_tempFolder.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
13
test/component/Elsa.ComponentTests/Helpers/AssetHelper.cs
Normal file
13
test/component/Elsa.ComponentTests/Helpers/AssetHelper.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Elsa.ComponentTests.Helpers
|
||||
{
|
||||
public static class AssetHelper
|
||||
{
|
||||
private static readonly string AssetsDirectory;
|
||||
static AssetHelper() => AssetsDirectory = Path.Combine(Path.GetDirectoryName(typeof(AssetHelper).Assembly.Location)!, "Assets");
|
||||
public static string GetAssetPath(string filename) => Path.Combine(AssetsDirectory, filename);
|
||||
public static Task<string> ReadAsset(string filename) => File.ReadAllTextAsync(Path.Combine(AssetsDirectory, filename));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
using Xunit;
|
||||
|
||||
namespace Elsa.ComponentTests.Helpers
|
||||
{
|
||||
[CollectionDefinition(Name)]
|
||||
public class ComponentTestsCollection : ICollectionFixture<ElsaHostApplicationFactory>
|
||||
{
|
||||
public const string Name = "Component Tests";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
using Elsa.Server.Host;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc.Testing;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace Elsa.ComponentTests.Helpers
|
||||
{
|
||||
public class ElsaHostApplicationFactory : WebApplicationFactory<Startup>
|
||||
{
|
||||
private string _dbConnectionString;
|
||||
|
||||
public void SetDbConnectionString(string connectionString)
|
||||
{
|
||||
_dbConnectionString = connectionString;
|
||||
}
|
||||
|
||||
protected override void ConfigureWebHost(IWebHostBuilder builder)
|
||||
{
|
||||
builder
|
||||
.ConfigureAppConfiguration(config => config.AddInMemoryCollection(FakeConfiguration.Create(_dbConnectionString)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Elsa.ComponentTests.Helpers
|
||||
{
|
||||
public static class FakeConfiguration
|
||||
{
|
||||
public static IEnumerable<KeyValuePair<string, string>> Create(string dbConnectionString)
|
||||
{
|
||||
return new Dictionary<string, string>
|
||||
{
|
||||
["ConnectionStrings:Sqlite"] = dbConnectionString,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Elsa.ComponentTests.Helpers
|
||||
{
|
||||
public static class HttpClientExtensions
|
||||
{
|
||||
public static async Task<T> GetJsonAsync<T>(this HttpClient httpClient, string requestUri)
|
||||
{
|
||||
using var response = await httpClient.GetAsync(requestUri);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
return await response.Content.ReadJsonAsync<T>();
|
||||
}
|
||||
|
||||
public static async Task<HttpResponseMessage> PostJsonAsync<T>(this HttpClient httpClient, string requestUri, T value) => await httpClient.PostAsync(requestUri, new JsonContent(value!));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Elsa.ComponentTests.Helpers
|
||||
{
|
||||
public static class HttpContentExtensions
|
||||
{
|
||||
public static async Task<T> ReadJsonAsync<T>(this HttpContent content)
|
||||
{
|
||||
var json = await content.ReadAsStringAsync();
|
||||
return JsonConvert.DeserializeObject<T>(json, JsonContent.SerializerSettings)!;
|
||||
}
|
||||
}
|
||||
}
|
||||
29
test/component/Elsa.ComponentTests/Helpers/JsonContent.cs
Normal file
29
test/component/Elsa.ComponentTests/Helpers/JsonContent.cs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using NodaTime;
|
||||
using NodaTime.Serialization.JsonNet;
|
||||
|
||||
namespace Elsa.ComponentTests.Helpers
|
||||
{
|
||||
public class JsonContent : StringContent
|
||||
{
|
||||
public static readonly JsonSerializerSettings SerializerSettings;
|
||||
|
||||
static JsonContent()
|
||||
{
|
||||
SerializerSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
|
||||
SerializerSettings.Converters.Add(new StringEnumConverter());
|
||||
}
|
||||
|
||||
public JsonContent(string content) : base(content, Encoding.UTF8, "application/json")
|
||||
{
|
||||
}
|
||||
|
||||
public JsonContent(object content) : this(JsonConvert.SerializeObject(content, SerializerSettings))
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
using System.Threading.Tasks;
|
||||
using Elsa.Core.IntegrationTests.Helpers;
|
||||
using Elsa.Core.IntegrationTests.Workflows;
|
||||
using Elsa.Models;
|
||||
using Elsa.Testing.Shared.Helpers;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Core.IntegrationTests
|
||||
{
|
||||
public class BasicWorkflowUnitTests : WorkflowsUnitTestBase
|
||||
{
|
||||
public BasicWorkflowUnitTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper)
|
||||
{
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Runs simple workflow.")]
|
||||
public async Task Test01()
|
||||
{
|
||||
var workflowInstance = await WorkflowHost.RunWorkflowAsync<BasicWorkflow>();
|
||||
|
||||
Assert.Equal(WorkflowStatus.Completed, workflowInstance.Status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,9 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
@ -33,8 +31,12 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\src\core\Elsa.Core\Elsa.Core.csproj" />
|
||||
<ProjectReference Include="..\..\..\src\core\Elsa\Elsa.csproj" />
|
||||
<ProjectReference Include="..\..\shared\Elsa.Testing.Shared\Elsa.Testing.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Helpers" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Core.IntegrationTests.Helpers;
|
||||
using Elsa.Core.IntegrationTests.Workflows;
|
||||
using Elsa.Testing.Shared.Helpers;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Core.IntegrationTests
|
||||
{
|
||||
public class ForLoopWorkflowUnitTests : WorkflowsUnitTestBase
|
||||
{
|
||||
public ForLoopWorkflowUnitTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper)
|
||||
{
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Runs For loop workflow.")]
|
||||
public async Task Test01()
|
||||
{
|
||||
const int loopCount = 10;
|
||||
var workflow = new ForLoopWorkflow(loopCount);
|
||||
var workflowInstance = await WorkflowHost.RunWorkflowAsync(workflow);
|
||||
var iterationLogs = workflowInstance.ExecutionLog.Where(x => x.ActivityId == "WriteLine").ToList();
|
||||
|
||||
Assert.Equal(loopCount, iterationLogs.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
using Elsa.Activities.Console;
|
||||
using Elsa.Builders;
|
||||
|
||||
namespace Elsa.Core.IntegrationTests.Workflows
|
||||
{
|
||||
public class BasicWorkflow : IWorkflow
|
||||
{
|
||||
public void Build(IWorkflowBuilder builder)
|
||||
{
|
||||
builder.WriteLine("Hello xUnit!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
using Elsa.Activities.Console;
|
||||
using Elsa.Activities.ControlFlow;
|
||||
using Elsa.Builders;
|
||||
|
||||
namespace Elsa.Core.IntegrationTests.Workflows
|
||||
{
|
||||
public class ForLoopWorkflow : IWorkflow
|
||||
{
|
||||
private readonly int _loopCount;
|
||||
|
||||
public ForLoopWorkflow(int loopCount)
|
||||
{
|
||||
_loopCount = loopCount;
|
||||
}
|
||||
|
||||
public void Build(IWorkflowBuilder builder)
|
||||
{
|
||||
builder.For(
|
||||
0,
|
||||
_loopCount,
|
||||
iterate => iterate
|
||||
.Then<WriteLine>(activity => activity.Set(x => x.Text, context => $"Iteration {context.Input}"))
|
||||
.WithId("WriteLine"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using AutoFixture.Kernel;
|
||||
|
||||
namespace Elsa.Testing.Shared.Autofixture.Abstractions
|
||||
namespace Elsa.Testing.Shared.AutoFixture.Abstractions
|
||||
{
|
||||
public abstract class SpecimenBuilderBase<T> : ISpecimenBuilder
|
||||
{
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
using AutoFixture;
|
||||
using Elsa.Testing.Shared.Autofixture.SpecimenBuilders;
|
||||
using Elsa.Testing.Shared.AutoFixture.SpecimenBuilders;
|
||||
|
||||
namespace Elsa.Testing.Shared.Autofixture
|
||||
namespace Elsa.Testing.Shared.AutoFixture
|
||||
{
|
||||
public class NodaTimeCustomization : ICustomization
|
||||
{
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
using System;
|
||||
using AutoFixture;
|
||||
using AutoFixture.Kernel;
|
||||
using Elsa.Testing.Shared.Autofixture.Abstractions;
|
||||
using Elsa.Testing.Shared.AutoFixture.Abstractions;
|
||||
using NodaTime;
|
||||
|
||||
namespace Elsa.Testing.Shared.Autofixture.SpecimenBuilders
|
||||
namespace Elsa.Testing.Shared.AutoFixture.SpecimenBuilders
|
||||
{
|
||||
public class DurationGenerator : SpecimenBuilderBase<Duration>
|
||||
{
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
using System;
|
||||
using AutoFixture;
|
||||
using AutoFixture.Kernel;
|
||||
using Elsa.Testing.Shared.Autofixture.Abstractions;
|
||||
using Elsa.Testing.Shared.AutoFixture.Abstractions;
|
||||
using NodaTime;
|
||||
|
||||
namespace Elsa.Testing.Shared.Autofixture.SpecimenBuilders
|
||||
namespace Elsa.Testing.Shared.AutoFixture.SpecimenBuilders
|
||||
{
|
||||
public class InstantGenerator : SpecimenBuilderBase<Instant>
|
||||
{
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
using System;
|
||||
using AutoFixture.Kernel;
|
||||
using Elsa.Testing.Shared.Autofixture.Abstractions;
|
||||
using Elsa.Testing.Shared.AutoFixture.Abstractions;
|
||||
using NodaTime;
|
||||
|
||||
namespace Elsa.Testing.Shared.Autofixture.SpecimenBuilders
|
||||
namespace Elsa.Testing.Shared.AutoFixture.SpecimenBuilders
|
||||
{
|
||||
public class LocalDateGenerator : SpecimenBuilderBase<LocalDate>
|
||||
{
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
using System;
|
||||
using AutoFixture;
|
||||
using AutoFixture.Kernel;
|
||||
using Elsa.Testing.Shared.Autofixture.Abstractions;
|
||||
using Elsa.Testing.Shared.AutoFixture.Abstractions;
|
||||
using NodaTime;
|
||||
|
||||
namespace Elsa.Testing.Shared.Autofixture.SpecimenBuilders
|
||||
namespace Elsa.Testing.Shared.AutoFixture.SpecimenBuilders
|
||||
{
|
||||
public class PeriodGenerator : SpecimenBuilderBase<Period>
|
||||
{
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<PackageVersion>1.0.0</PackageVersion>
|
||||
<Authors>Elsa Contributors</Authors>
|
||||
|
|
@ -19,7 +19,10 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoFixture" Version="4.14.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.9" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.9" />
|
||||
<PackageReference Include="NodaTime" Version="3.0.2" />
|
||||
<PackageReference Include="xunit.extensibility.core" Version="2.4.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
@ -29,4 +32,8 @@
|
|||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\src\core\Elsa\Elsa.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Elsa.Core.UnitTests
|
||||
namespace Elsa.Core.IntegrationTests.Helpers
|
||||
{
|
||||
public class TemporaryFolder : IDisposable
|
||||
{
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Core.IntegrationTests.Helpers;
|
||||
using Elsa.Services;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
using YesSql;
|
||||
using YesSql.Provider.Sqlite;
|
||||
|
||||
namespace Elsa.Testing.Shared.Helpers
|
||||
{
|
||||
public abstract class WorkflowsUnitTestBase : IAsyncLifetime, IDisposable
|
||||
{
|
||||
private readonly TemporaryFolder _tempFolder;
|
||||
|
||||
protected WorkflowsUnitTestBase(ITestOutputHelper testOutputHelper, Action<IServiceCollection>? configureServices = default)
|
||||
{
|
||||
_tempFolder = new TemporaryFolder();
|
||||
TestOutputHelper = testOutputHelper;
|
||||
|
||||
var services = new ServiceCollection()
|
||||
.AddElsa(options => options.UsePersistence(config => ConfigurePersistence(config, _tempFolder.Folder)))
|
||||
.AddConsoleActivities(Console.In, new XunitConsoleForwarder(testOutputHelper));
|
||||
|
||||
configureServices?.Invoke(services);
|
||||
ServiceProvider = services.BuildServiceProvider();
|
||||
WorkflowHost = ServiceProvider.GetRequiredService<IWorkflowHost>();
|
||||
}
|
||||
|
||||
protected ITestOutputHelper TestOutputHelper { get; }
|
||||
protected ServiceProvider ServiceProvider { get; }
|
||||
protected IWorkflowHost WorkflowHost { get; }
|
||||
public virtual void Dispose() => _tempFolder.Dispose();
|
||||
|
||||
public virtual async Task InitializeAsync()
|
||||
{
|
||||
var startupRunner = ServiceProvider.GetRequiredService<IStartupRunner>();
|
||||
await startupRunner.StartupAsync();
|
||||
}
|
||||
|
||||
public virtual async Task DisposeAsync()
|
||||
{
|
||||
await ServiceProvider.DisposeAsync();
|
||||
Dispose();
|
||||
}
|
||||
|
||||
private void ConfigurePersistence(IConfiguration configuration, string folder)
|
||||
{
|
||||
var connectionString = $@"Data Source={folder}elsa.db;Cache=Shared";
|
||||
configuration.UseSqLite(connectionString).UseDefaultIdGenerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Core.IntegrationTests.Helpers
|
||||
{
|
||||
public class XunitConsoleForwarder : TextWriter
|
||||
{
|
||||
private readonly ITestOutputHelper _output;
|
||||
private IList<char> _line = new List<char>();
|
||||
public XunitConsoleForwarder(ITestOutputHelper output) => _output = output;
|
||||
public override Encoding Encoding => Console.Out.Encoding;
|
||||
|
||||
public override void Write(char value)
|
||||
{
|
||||
if (value == '\n')
|
||||
{
|
||||
FlushLine();
|
||||
_line = new List<char>();
|
||||
return;
|
||||
}
|
||||
|
||||
_line.Add(value);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (_line.Count > 0)
|
||||
FlushLine();
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
private void FlushLine()
|
||||
{
|
||||
if (_line.Count > 0 && _line.Last() == '\r')
|
||||
_line.RemoveAt(_line.Count - 1);
|
||||
|
||||
_output.WriteLine(new string(_line.ToArray()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
// using System;
|
||||
// using System.Threading;
|
||||
// using System.Threading.Tasks;
|
||||
// using AutoFixture;
|
||||
// using Elsa.ActivityResults;
|
||||
// using Elsa.Expressions;
|
||||
// using Elsa.Models;
|
||||
// using Elsa.Services;
|
||||
// using Elsa.Services.Models;
|
||||
// using Elsa.Testing.Shared.Autofixture;
|
||||
// using MediatR;
|
||||
// using Microsoft.Extensions.DependencyInjection;
|
||||
// using Microsoft.Extensions.Logging.Abstractions;
|
||||
// using Moq;
|
||||
// using NodaTime;
|
||||
// using NodaTime.Testing;
|
||||
// using Xunit;
|
||||
// using YesSql;
|
||||
// using YesSql.Provider.Sqlite;
|
||||
//
|
||||
// namespace Elsa.Core.UnitTests
|
||||
// {
|
||||
// public class WorkflowHostTests : IDisposable
|
||||
// {
|
||||
// private readonly IFixture _fixture;
|
||||
// private readonly WorkflowHost _workflowHost;
|
||||
// private TemporaryFolder _tempFolder;
|
||||
// private ISession _session;
|
||||
//
|
||||
// public WorkflowHostTests()
|
||||
// {
|
||||
// _fixture = new Fixture().Customize(new NodaTimeCustomization());
|
||||
// _session = CreateSession();
|
||||
//
|
||||
// var workflowActivatorMock = new Mock<IWorkflowFactory>();
|
||||
// var workflowRegistryMock = new Mock<IWorkflowRegistry>();
|
||||
// var workflowInstanceManager = new WorkflowInstanceManager(_session);
|
||||
// var workflowExpressionEvaluatorMock = new Mock<IExpressionEvaluator>();
|
||||
// var mediatorMock = new Mock<IMediator>();
|
||||
// var now = _fixture.Create<Instant>();
|
||||
// var clock = new FakeClock(now);
|
||||
// var logger = new NullLogger<WorkflowHost>();
|
||||
// var serviceProvider = new ServiceCollection().BuildServiceProvider();
|
||||
//
|
||||
// workflowActivatorMock
|
||||
// .Setup(x => x.InstantiateAsync(It.IsAny<WorkflowBlueprint>(), It.IsAny<string?>(), It.IsAny<CancellationToken>()))
|
||||
// .ReturnsAsync((WorkflowBlueprint workflow, string? correlationId, CancellationToken cancellationToken) => new WorkflowInstance());
|
||||
//
|
||||
// _workflowHost = new WorkflowHost(
|
||||
// workflowInstanceManager,
|
||||
// workflowRegistryMock.Object,
|
||||
// workflowActivatorMock.Object,
|
||||
// workflowExpressionEvaluatorMock.Object,
|
||||
// clock,
|
||||
// mediatorMock.Object,
|
||||
// serviceProvider,
|
||||
// logger);
|
||||
// }
|
||||
//
|
||||
// public void Dispose() => _session.Dispose();
|
||||
//
|
||||
// private ISession CreateSession()
|
||||
// {
|
||||
// _tempFolder = new TemporaryFolder();
|
||||
// var connectionString = $@"Data Source={_tempFolder.Folder}elsa.db;Cache=Shared";
|
||||
// var config = new Configuration().UseSqLite(connectionString).UseDefaultIdGenerator();
|
||||
// var store = StoreFactory.CreateAndInitializeAsync(config).GetAwaiter().GetResult();
|
||||
// return store.CreateSession();
|
||||
// }
|
||||
//
|
||||
// [Fact(DisplayName = "Can run simple workflow to completed state.")]
|
||||
// public async Task RunAsync01()
|
||||
// {
|
||||
// var activityExecutionResultMock = new Mock<IActivityExecutionResult>();
|
||||
// var activity = CreateActivity(activityExecutionResult: activityExecutionResultMock.Object);
|
||||
// var workflow = CreateWorkflow(activity);
|
||||
// var executionContext = await _workflowHost.RunWorkflowAsync(workflow);
|
||||
//
|
||||
// Assert.Equal(WorkflowStatus.Completed, executionContext.UpdateWorkflowInstance().Status);
|
||||
// }
|
||||
//
|
||||
// [Fact(DisplayName = "Invokes returned activity execution result.")]
|
||||
// public async Task RunAsync02()
|
||||
// {
|
||||
// var activityExecutionResultMock = new Mock<IActivityExecutionResult>();
|
||||
// var activity = CreateActivity(true, activityExecutionResultMock.Object);
|
||||
// var workflow = CreateWorkflow(activity);
|
||||
// var executionContext = await _workflowHost.RunWorkflowAsync(workflow);
|
||||
//
|
||||
// activityExecutionResultMock
|
||||
// .Verify(x => x.ExecuteAsync(It.IsAny<ActivityExecutionContext>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
// }
|
||||
//
|
||||
// private IActivity CreateActivity(bool canExecute = true, IActivityExecutionResult? activityExecutionResult = null)
|
||||
// {
|
||||
// var activityMock = new Mock<IActivity>();
|
||||
// var activityId = _fixture.Create<string>();
|
||||
//
|
||||
// activityMock.Setup(x => x.Id).Returns(activityId);
|
||||
//
|
||||
// activityMock
|
||||
// .Setup(x => x.CanExecuteAsync(It.IsAny<ActivityExecutionContext>(), It.IsAny<CancellationToken>()))
|
||||
// .ReturnsAsync(canExecute);
|
||||
//
|
||||
// if (activityExecutionResult != null)
|
||||
// activityMock
|
||||
// .Setup(x => x.ExecuteAsync(It.IsAny<ActivityExecutionContext>(), It.IsAny<CancellationToken>()))
|
||||
// .ReturnsAsync(activityExecutionResult);
|
||||
//
|
||||
// return activityMock.Object;
|
||||
// }
|
||||
//
|
||||
// private WorkflowBlueprint CreateWorkflow(IActivity activity)
|
||||
// {
|
||||
// var workflow = new WorkflowBlueprint();
|
||||
// workflow.Activities.Add(activity);
|
||||
// return workflow;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
Loading…
Reference in a new issue