diff --git a/src/Persistence/MartenTests/validate_empty_stream_key_on_start_stream.cs b/src/Persistence/MartenTests/validate_empty_stream_key_on_start_stream.cs new file mode 100644 index 00000000..50916c18 --- /dev/null +++ b/src/Persistence/MartenTests/validate_empty_stream_key_on_start_stream.cs @@ -0,0 +1,69 @@ +using IntegrationTests; +using Marten; +using Marten.Events; +using MartenTests.Distribution.TripDomain; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Oakton.Resources; +using Shouldly; +using Wolverine; +using Wolverine.Marten; + +namespace MartenTests; + +public class validate_empty_stream_key_on_start_stream: PostgresqlContext, IAsyncLifetime +{ + private IHost _host; + private IDocumentStore _store; + + public async Task InitializeAsync() + { + _host = await Host.CreateDefaultBuilder() + .UseWolverine(opts => + { + opts.Services + .AddMarten(m => + { + m.Connection(Servers.PostgresConnectionString); + m.DatabaseSchemaName = "start_stream"; + m.Events.StreamIdentity = StreamIdentity.AsString; + }) + .IntegrateWithWolverine(); + + opts.Policies.AutoApplyTransactions(); + + opts.Services.AddResourceSetupOnStartup(); + }).StartAsync(); + + _store = _host.Services.GetRequiredService(); + + await _store.Advanced.Clean.DeleteDocumentsByTypeAsync(typeof(NamedDocument)); + } + + public async Task DisposeAsync() + { + await _host.StopAsync(); + _host.Dispose(); + } + + [Fact] + public void assert_empty_stream_key() + { + using var session = _store.LightweightSession(); + + // No stream key supplied + var op = MartenOps.StartStream(new TripStarted()); + + Should.Throw(() => op.Execute(session)); + } + + [Fact] + public void happy_path_execution() + { + using var session = _store.LightweightSession(); + + // No stream key supplied + var op = MartenOps.StartStream("a good key", new TripStarted()); + op.Execute(session); + } +} \ No newline at end of file diff --git a/src/Persistence/Wolverine.Marten/IMartenOp.cs b/src/Persistence/Wolverine.Marten/IMartenOp.cs index fb43217c..ece59301 100644 --- a/src/Persistence/Wolverine.Marten/IMartenOp.cs +++ b/src/Persistence/Wolverine.Marten/IMartenOp.cs @@ -4,6 +4,8 @@ using JasperFx.CodeGeneration.Model; using JasperFx.Core; using Marten; +using Marten.Events; +using Marten.Internal.Sessions; using Wolverine.Configuration; using Wolverine.Marten.Persistence.Sagas; using Wolverine.Runtime; @@ -358,6 +360,13 @@ public StartStream With(object @event) public void Execute(IDocumentSession session) { + if (session is DocumentSessionBase s && s.Options.Events.StreamIdentity == StreamIdentity.AsString && + StreamKey.IsEmpty()) + { + throw new InvalidOperationException( + "The event stream identity is string, but the StreamKey is empty or null"); + } + if (StreamId == Guid.Empty) { if (StreamKey.IsNotEmpty())