public void OrderPostSavePipelineHooksByOrderThenByNameReversed()
            {
                var pipelineHooks = new PipelineHook[] { new PipelineHookC(), new PipelineHookA(), new PipelineHookB() };
                var sagaStore = new HookableSagaStore(new Mock<IStoreSagas>().Object, pipelineHooks);
                var postSaveHooks = sagaStore.PostSaveHooks.AsList();

                Assert.IsType(typeof(PipelineHookA), postSaveHooks[0]);
                Assert.IsType(typeof(PipelineHookC), postSaveHooks[1]);
                Assert.IsType(typeof(PipelineHookB), postSaveHooks[2]);
            }
            public void OrderPostSavePipelineHooksByOrderThenByNameReversed()
            {
                var pipelineHooks = new PipelineHook[] { new PipelineHookC(), new PipelineHookA(), new PipelineHookB() };
                var sagaStore     = new HookableSagaStore(new Mock <IStoreSagas>().Object, pipelineHooks);
                var postSaveHooks = sagaStore.PostSaveHooks.AsList();

                Assert.IsType(typeof(PipelineHookA), postSaveHooks[0]);
                Assert.IsType(typeof(PipelineHookC), postSaveHooks[1]);
                Assert.IsType(typeof(PipelineHookB), postSaveHooks[2]);
            }
            public void DelegateToDecoratedSagaStore()
            {
                var sagaStore = new Mock <IStoreSagas>();

                using (var cachedSagaStore = new HookableSagaStore(sagaStore.Object, new PipelineHook[0]))
                {
                    cachedSagaStore.Purge();

                    sagaStore.Verify(mock => mock.Purge(), Times.Once());
                }
            }
            public void CanCallDisposeMoreThanOnce()
            {
                var pipelineHook  = new DisposablePipelineHook();
                var pipelineHooks = new PipelineHook[] { pipelineHook };
                var sagaStore     = new HookableSagaStore(new Mock <IStoreSagas>().Object, pipelineHooks);

                sagaStore.Dispose();
                sagaStore.Dispose();

                Assert.True(pipelineHook.Disposed);
            }
            public void DelegateToDecoratedSagaStore()
            {
                var sagaStore  = new Mock <IStoreSagas>();
                var upperBound = DateTime.Now;

                using (var cachedSagaStore = new HookableSagaStore(sagaStore.Object, new PipelineHook[0]))
                {
                    cachedSagaStore.GetScheduledTimeouts(upperBound);

                    sagaStore.Verify(mock => mock.GetScheduledTimeouts(upperBound), Times.Once());
                }
            }
            public void ReturnSagaIfNoExceptionsThrown()
            {
                var id                 = Guid.NewGuid();
                var type               = typeof(Saga);
                var saga               = new Mock <Saga>();
                var pipelineHook       = new Mock <PipelineHook>();
                var decoratedSagaStore = new Mock <IStoreSagas>();
                var sagaStore          = new HookableSagaStore(decoratedSagaStore.Object, new[] { pipelineHook.Object });

                decoratedSagaStore.Setup(mock => mock.CreateSaga(type, id)).Returns(saga.Object);

                Assert.Same(saga.Object, sagaStore.CreateSaga(type, id));
            }
            public void ReturnSagaIfNoExceptionsThrown()
            {
                var id                 = Guid.NewGuid();
                var type               = typeof(Saga);
                var saga               = default(Saga);
                var pipelineHook       = new Mock <PipelineHook>();
                var decoratedSagaStore = new Mock <IStoreSagas>();
                var sagaStore          = new HookableSagaStore(decoratedSagaStore.Object, new[] { pipelineHook.Object });

                decoratedSagaStore.Setup(mock => mock.TryGetSaga(type, id, out saga)).Returns(true);

                Assert.True(sagaStore.TryGetSaga(type, id, out saga));
            }
            public void InvokePreGetHooksBeforeDecoratedGet()
            {
                var id                 = Guid.NewGuid();
                var type               = typeof(Saga);
                var pipelineHook       = new Mock <PipelineHook>();
                var decoratedSagaStore = new Mock <IStoreSagas>();
                var sagaStore          = new HookableSagaStore(decoratedSagaStore.Object, new[] { pipelineHook.Object });

                pipelineHook.Setup(mock => mock.PreGet(type, id)).Throws(new InvalidOperationException());

                Assert.Throws <InvalidOperationException>(() => sagaStore.CreateSaga(type, id));

                decoratedSagaStore.Verify(mock => mock.CreateSaga(type, id), Times.Never());
            }
            public void InvokePostGetHooksAfterDecoratedGet()
            {
                var id                 = Guid.NewGuid();
                var type               = typeof(Saga);
                var saga               = default(Saga);
                var pipelineHook       = new Mock <PipelineHook>();
                var decoratedSagaStore = new Mock <IStoreSagas>();
                var sagaStore          = new HookableSagaStore(decoratedSagaStore.Object, new[] { pipelineHook.Object });

                decoratedSagaStore.Setup(mock => mock.TryGetSaga(type, id, out saga)).Returns(true);
                pipelineHook.Setup(mock => mock.PostGet(saga)).Throws(new InvalidOperationException());

                Assert.Throws <InvalidOperationException>(() => sagaStore.TryGetSaga(type, id, out saga));

                decoratedSagaStore.Verify(mock => mock.TryGetSaga(type, id, out saga), Times.Once());
            }
            public void ReturnSaveResultIfNoExceptionsThrown()
            {
                var saga               = new Mock <Saga>();
                var pipelineHook       = new Mock <PipelineHook>();
                var decoratedSagaStore = new Mock <IStoreSagas>();
                var sagaStore          = new HookableSagaStore(decoratedSagaStore.Object, new[] { pipelineHook.Object });

                // ReSharper disable AccessToDisposedClosure
                using (var context = new SagaContext(typeof(Saga), Guid.NewGuid(), new FakeEvent()))
                {
                    decoratedSagaStore.Setup(mock => mock.Save(saga.Object, context)).Returns(saga.Object);

                    Assert.Same(saga.Object, sagaStore.Save(saga.Object, context));
                }
                // ReSharper restore AccessToDisposedClosure
            }
            public void InvokePreSaveHooksBeforeDecoratedSave()
            {
                var saga               = new Mock <Saga>();
                var pipelineHook       = new Mock <PipelineHook>();
                var decoratedSagaStore = new Mock <IStoreSagas>();
                var sagaStore          = new HookableSagaStore(decoratedSagaStore.Object, new[] { pipelineHook.Object });

                // ReSharper disable AccessToDisposedClosure
                using (var context = new SagaContext(typeof(Saga), Guid.NewGuid(), new FakeEvent()))
                {
                    pipelineHook.Setup(mock => mock.PreSave(saga.Object, context)).Throws(new InvalidOperationException());

                    Assert.Throws <InvalidOperationException>(() => sagaStore.Save(saga.Object, context));

                    decoratedSagaStore.Verify(mock => mock.Save(saga.Object, context), Times.Never());
                }
                // ReSharper restore AccessToDisposedClosure
            }
            public void InvokePreGetHooksBeforeDecoratedGet()
            {
                var id = Guid.NewGuid();
                var type = typeof(Saga);
                var pipelineHook = new Mock<PipelineHook>();
                var decoratedSagaStore = new Mock<IStoreSagas>();
                var sagaStore = new HookableSagaStore(decoratedSagaStore.Object, new[] { pipelineHook.Object });

                pipelineHook.Setup(mock => mock.PreGet(type, id)).Throws(new InvalidOperationException());

                Assert.Throws<InvalidOperationException>(() => sagaStore.CreateSaga(type, id));

                decoratedSagaStore.Verify(mock => mock.CreateSaga(type, id), Times.Never());
            }
            public void InvokePostGetHooksAfterDecoratedGet()
            {
                var id = Guid.NewGuid();
                var type = typeof(Saga);
                var saga = default(Saga);
                var pipelineHook = new Mock<PipelineHook>();
                var decoratedSagaStore = new Mock<IStoreSagas>();
                var sagaStore = new HookableSagaStore(decoratedSagaStore.Object, new[] { pipelineHook.Object });

                decoratedSagaStore.Setup(mock => mock.TryGetSaga(type, id, out saga)).Returns(true);
                pipelineHook.Setup(mock => mock.PostGet(saga)).Throws(new InvalidOperationException());

                Assert.Throws<InvalidOperationException>(() => sagaStore.TryGetSaga(type, id, out saga));

                decoratedSagaStore.Verify(mock => mock.TryGetSaga(type, id, out saga), Times.Once());
            }
            public void ReturnSagaIfNoExceptionsThrown()
            {
                var id = Guid.NewGuid();
                var type = typeof(Saga);
                var saga = default(Saga);
                var pipelineHook = new Mock<PipelineHook>();
                var decoratedSagaStore = new Mock<IStoreSagas>();
                var sagaStore = new HookableSagaStore(decoratedSagaStore.Object, new[] { pipelineHook.Object });

                decoratedSagaStore.Setup(mock => mock.TryGetSaga(type, id, out saga)).Returns(true);

                Assert.True(sagaStore.TryGetSaga(type, id, out saga));
            }
            public void DelegateToDecoratedSagaStore()
            {
                var sagaStore = new Mock<IStoreSagas>();
                var upperBound = DateTime.Now;

                using (var cachedSagaStore = new HookableSagaStore(sagaStore.Object, new PipelineHook[0]))
                {
                    cachedSagaStore.GetScheduledTimeouts(upperBound);

                    sagaStore.Verify(mock => mock.GetScheduledTimeouts(upperBound), Times.Once());
                }
            }
            public void InvokePostSaveHooksIfDecoratedSaveThrowsException()
            {
                var saga = new Mock<Saga>();
                var pipelineHook = new Mock<PipelineHook>();
                var error = new InvalidOperationException();
                var decoratedSagaStore = new Mock<IStoreSagas>();
                var sagaStore = new HookableSagaStore(decoratedSagaStore.Object, new[] { pipelineHook.Object });

                // ReSharper disable AccessToDisposedClosure
                using (var context = new SagaContext(typeof(Saga), Guid.NewGuid(), new FakeEvent()))
                {
                    decoratedSagaStore.Setup(mock => mock.Save(saga.Object, context)).Throws(error);

                    Assert.Throws<InvalidOperationException>(() => sagaStore.Save(saga.Object, context));

                    pipelineHook.Verify(mock => mock.PostSave(saga.Object, context, error), Times.Once());
                }
                // ReSharper restore AccessToDisposedClosure
            }
            public void ReturnSaveResultIfNoExceptionsThrown()
            {
                var saga = new Mock<Saga>();
                var pipelineHook = new Mock<PipelineHook>();
                var decoratedSagaStore = new Mock<IStoreSagas>();
                var sagaStore = new HookableSagaStore(decoratedSagaStore.Object, new[] { pipelineHook.Object });

                // ReSharper disable AccessToDisposedClosure
                using (var context = new SagaContext(typeof(Saga), Guid.NewGuid(), new FakeEvent()))
                {
                    decoratedSagaStore.Setup(mock => mock.Save(saga.Object, context)).Returns(saga.Object);

                    Assert.Same(saga.Object, sagaStore.Save(saga.Object, context));
                }
                // ReSharper restore AccessToDisposedClosure
            }
            public void ReturnSagaIfNoExceptionsThrown()
            {
                var id = Guid.NewGuid();
                var type = typeof(Saga);
                var saga = new Mock<Saga>();
                var pipelineHook = new Mock<PipelineHook>();
                var decoratedSagaStore = new Mock<IStoreSagas>();
                var sagaStore = new HookableSagaStore(decoratedSagaStore.Object, new[] { pipelineHook.Object });

                decoratedSagaStore.Setup(mock => mock.CreateSaga(type, id)).Returns(saga.Object);

                Assert.Same(saga.Object, sagaStore.CreateSaga(type, id));
            }
            public void DelegateToDecoratedSagaStore()
            {
                var sagaStore = new Mock<IStoreSagas>();

                using (var cachedSagaStore = new HookableSagaStore(sagaStore.Object, new PipelineHook[0]))
                {
                    cachedSagaStore.Purge();

                    sagaStore.Verify(mock => mock.Purge(), Times.Once());
                }
            }
            public void CanCallDisposeMoreThanOnce()
            {
                var pipelineHook = new DisposablePipelineHook();
                var pipelineHooks = new PipelineHook[] { pipelineHook };
                var sagaStore = new HookableSagaStore(new Mock<IStoreSagas>().Object, pipelineHooks);

                sagaStore.Dispose();
                sagaStore.Dispose();

                Assert.True(pipelineHook.Disposed);
            }