diff --git a/.editorconfig b/.editorconfig index 05ddf8d..9b9b929 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,7 +11,7 @@ indent_style = tab end_of_line = crlf insert_final_newline = true -[*.csproj] +[{*.csproj,*.props}] indent_size = 2 indent_style = space end_of_line = crlf diff --git a/Directory.Packages.props b/Directory.Packages.props index 1fe41be..48f5df3 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -30,4 +30,9 @@ + + + + + diff --git a/tests/rm.DelegatingHandlersTest/SagaTesting.cs b/tests/rm.DelegatingHandlersTest/SagaTesting.cs new file mode 100644 index 0000000..bf88746 --- /dev/null +++ b/tests/rm.DelegatingHandlersTest/SagaTesting.cs @@ -0,0 +1,299 @@ +using AutoFixture; +using AutoFixture.AutoMoq; +using NServiceBus; +using NServiceBus.Testing; +using NUnit.Framework; + +namespace NsbTesting; + +public class OrderSagaHander : + NServiceBus.Saga, + IAmStartedByMessages, + IHandleMessages +{ + protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper) + { + mapper.MapSaga(saga => saga.OrderId) + .ToMessage(message => message.OrderId) + .ToMessage(message => message.OrderId) + ; + } + + public async Task Handle(StartOrder message, IMessageHandlerContext context) + { + Data.DramaProperty = "StartOrder"; + + // work + + //return Task.CompletedTask; + await context.Send( + new CompleteOrder() + { + OrderId = message.OrderId + }); + } + + public Task Handle(CompleteOrder message, IMessageHandlerContext context) + { + Data.DramaProperty = "CompleteOrder"; + + // work + + //MarkAsComplete(); + return Task.CompletedTask; + } +} + +public class OrderSagaData : + ContainSagaData +{ + public string OrderId { get; set; } + public string DramaProperty { get; set; } +} + +public class StartOrder : ICommand +{ + public string OrderId { get; set; } +} +public class CompleteOrder : ICommand +{ + public string OrderId { get; set; } +} + +public class TransactionSagaHander : + NServiceBus.Saga, + IAmStartedByMessages, + IHandleMessages, + IHandleMessages, + IHandleMessages +{ + protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper) + { + mapper.MapSaga(saga => saga.OrderId) + .ToMessage(message => message.OrderId) + .ToMessage(message => message.OrderId) + .ToMessage(message => message.OrderId) + .ToMessage(message => message.OrderId) + ; + } + + public async Task Handle(StartOrder message, IMessageHandlerContext context) + { + Data.DramaProperty = "StartOrder"; + + // work + + //return Task.CompletedTask; + await context.Send( + new Step1Order() + { + OrderId = message.OrderId + }); + } + + public async Task Handle(Step1Order message, IMessageHandlerContext context) + { + Data.DramaProperty = "Step1Order"; + + // work + + //return Task.CompletedTask; + await context.Send( + new Step2Order() + { + OrderId = message.OrderId + }); + } + + public async Task Handle(Step2Order message, IMessageHandlerContext context) + { + Data.DramaProperty = "Step2Order"; + + // work + + //return Task.CompletedTask; + await context.Send( + new CompleteOrder() + { + OrderId = message.OrderId + }); + } + + public Task Handle(CompleteOrder message, IMessageHandlerContext context) + { + Data.DramaProperty = "CompleteOrder"; + + // work + + //MarkAsComplete(); + return Task.CompletedTask; + } +} + +public class Step1Order : ICommand +{ + public string OrderId { get; set; } +} +public class Step2Order : ICommand +{ + public string OrderId { get; set; } +} + +public class OrderSagaTests +{ + [Test] + public async Task __Verify_SagaData() + { + var fixture = new Fixture().Customize(new AutoMoqCustomization()); + var orderSagaData = fixture.Build() + .With(x => x.OrderId, "orderId") + .With(x => x.DramaProperty, "NONE") + .Create(); + var handler = new OrderSagaHander + { + Data = orderSagaData + }; + + var startOrder = fixture.Build().With(x => x.OrderId, "orderId").Create(); + var context = new TestableMessageHandlerContext(); + + await handler.Handle(startOrder, context); + + Assert.AreEqual("orderId", orderSagaData.OrderId); + Assert.AreEqual("StartOrder", orderSagaData.DramaProperty); + } + + [Test] + public async Task __Verify_SagaData_Using_Testing() + { + var fixture = new Fixture().Customize(new AutoMoqCustomization()); + var orderSagaData = fixture.Build() + .With(x => x.OrderId, "orderId") + .With(x => x.DramaProperty, "NONE") + .Create(); + var handler = fixture.Build().With(saga => saga.Data, orderSagaData).Create(); + + var testableSaga = new TestableSaga(sagaFactory: () => handler); + + var startOrder = fixture.Build().With(x => x.OrderId, "orderId").Create(); + var context = new TestableMessageHandlerContext(); + + var startOrderResult = await testableSaga.Handle(startOrder, context); + + var orderSagaDataSnapshot = startOrderResult.SagaDataSnapshot; + + Assert.AreEqual("orderId", orderSagaData.OrderId); + Assert.AreEqual("NONE", orderSagaData.DramaProperty); + + Assert.AreEqual("orderId", orderSagaDataSnapshot.OrderId); + Assert.AreEqual("StartOrder", orderSagaDataSnapshot.DramaProperty); + + var completeOrder = startOrderResult.FindSentMessage(); + Assert.IsNotNull(completeOrder); + Assert.AreEqual("orderId", completeOrder.OrderId); + + var completeOrderResult = await testableSaga.Handle(completeOrder, context); + + orderSagaDataSnapshot = completeOrderResult.SagaDataSnapshot; + + Assert.AreEqual("orderId", orderSagaDataSnapshot.OrderId); + Assert.AreEqual("CompleteOrder", orderSagaDataSnapshot.DramaProperty); + } +} + +public class TransactionSagaTests +{ + [Test] + public async Task __Verify_Transaction_SagaData() + { + var fixture = new Fixture().Customize(new AutoMoqCustomization()); + var orderSagaData = fixture.Build() + .With(x => x.OrderId, "orderId") + .With(x => x.DramaProperty, "NONE") + .Create(); + var handler = new TransactionSagaHander + { + Data = orderSagaData + }; + + var startOrder = fixture.Build().With(x => x.OrderId, "orderId").Create(); + var context = new TestableMessageHandlerContext(); + + await handler.Handle(startOrder, context); + + Assert.AreEqual("orderId", orderSagaData.OrderId); + Assert.AreEqual("StartOrder", orderSagaData.DramaProperty); + } + + [Test] + public async Task __Verify_Transaction_SagaData_Using_Testing() + { + var fixture = new Fixture().Customize(new AutoMoqCustomization()); + var orderSagaData = fixture.Build() + .With(x => x.OrderId, "orderId") + .With(x => x.DramaProperty, "NONE") + .Create(); + var handler = fixture.Build().With(saga => saga.Data, orderSagaData).Create(); + + var testableSaga = new TestableSaga(sagaFactory: () => handler); + + var startOrder = fixture.Build().With(x => x.OrderId, "orderId").Create(); + var context = new TestableMessageHandlerContext(); + + var startOrderResult = await testableSaga.Handle(startOrder, context); + + var orderSagaDataSnapshot = startOrderResult.SagaDataSnapshot; + + Assert.AreEqual("orderId", orderSagaData.OrderId); + Assert.AreEqual("NONE", orderSagaData.DramaProperty); + + Assert.AreEqual("orderId", orderSagaDataSnapshot.OrderId); + Assert.AreEqual("StartOrder", orderSagaDataSnapshot.DramaProperty); + + var step1Order = startOrderResult.FindSentMessage(); + Assert.IsNotNull(step1Order); + Assert.AreEqual("orderId", step1Order.OrderId); + + var completeOrderResult = await testableSaga.Handle(step1Order, context); + + orderSagaDataSnapshot = completeOrderResult.SagaDataSnapshot; + + Assert.AreEqual("orderId", orderSagaDataSnapshot.OrderId); + Assert.AreEqual("Step1Order", orderSagaDataSnapshot.DramaProperty); + } + + [Test] + public async Task __Verify_Transaction_SagaData_Using_Testing_Previously() + { + var fixture = new Fixture().Customize(new AutoMoqCustomization()); + var orderSagaData = fixture.Build() + .With(x => x.OrderId, "orderId") + .With(x => x.DramaProperty, "NONE") + .Create(); + var handler = fixture.Build().With(saga => saga.Data, orderSagaData).Create(); + + var testableSaga = new TestableSaga(sagaFactory: () => handler); + + var step2Order = fixture.Build().With(x => x.OrderId, "orderId").Create(); + var context = new TestableMessageHandlerContext(); + + // i should be able to run this test picking up from step2, + // step2order -> completeOrder + // so i do not have to construct the whole scenario, + // startOrder -> step1Order -> step2order -> completeOrder + // + // but this test throws, + // System.Exception : Saga not found and message type NsbTesting.Step2Order is not allowed to start the saga. + // this helps to slice the tests into small scenarios versus havin to repeat the scearnios leading up to step2 + var startOrderResult = await testableSaga.Handle(step2Order, context); + + var orderSagaDataSnapshot = startOrderResult.SagaDataSnapshot; + + Assert.AreEqual("orderId", orderSagaDataSnapshot.OrderId); + Assert.AreEqual("Step2Order", orderSagaDataSnapshot.DramaProperty); + + var completeOrder = startOrderResult.FindSentMessage(); + Assert.IsNotNull(completeOrder); + Assert.AreEqual("orderId", completeOrder.OrderId); + } +} diff --git a/tests/rm.DelegatingHandlersTest/StartOrder.cs b/tests/rm.DelegatingHandlersTest/StartOrder.cs new file mode 100644 index 0000000..550e406 --- /dev/null +++ b/tests/rm.DelegatingHandlersTest/StartOrder.cs @@ -0,0 +1,2 @@ +namespace rm.DelegatingHandlersTest; + diff --git a/tests/rm.DelegatingHandlersTest/rm.DelegatingHandlersTest.csproj b/tests/rm.DelegatingHandlersTest/rm.DelegatingHandlersTest.csproj index b0eb058..094f61a 100644 --- a/tests/rm.DelegatingHandlersTest/rm.DelegatingHandlersTest.csproj +++ b/tests/rm.DelegatingHandlersTest/rm.DelegatingHandlersTest.csproj @@ -1,7 +1,7 @@  - net8.0;net6.0;net7.0;net48;net472;net462 + net6.0 latest enable enable @@ -26,6 +26,11 @@ + + + + +