public void StateEngineTest()
        {
            {
                var orderState = new StateDefinition <Order, OrderState>(
                    x => x.State,
                    new StateTransitionDefinition <Order, OrderState>(OrderState.Init, OrderState.Confirmed),
                    new StateTransitionDefinition <Order, OrderState>(OrderState.Confirmed, OrderState.Processing),
                    new StateTransitionDefinition <Order, OrderState>(OrderState.Processing, OrderState.Done)
                {
                    Expect = (entity, o) => entity.Delivery.State == DeliveryState.Done
                }
                    );

                var deliveryState = new StateDefinition <Delivery, DeliveryState>(
                    x => x.State,
                    new StateTransitionDefinition <Delivery, DeliveryState>(DeliveryState.Init, DeliveryState.Prepare)
                {
                    Expect = (entity, o) => entity.Order.State == OrderState.Processing
                },
                    new StateTransitionDefinition <Delivery, DeliveryState>(DeliveryState.Prepare, DeliveryState.Sent)
                {
                    Expect = (entity, o) => entity.Order.State == OrderState.Processing
                },
                    new StateTransitionDefinition <Delivery, DeliveryState>(DeliveryState.Sent, DeliveryState.Done)
                {
                    PostAction = (container, entity, arg3) => container.StateEngine.Execute(entity.Order, OrderState.Done)
                }
                    );

                StateEngine.Add(orderState);
                StateEngine.Add(deliveryState);
            }

            {
                var order    = new Order();
                var delivery = new Delivery {
                    Order = order
                };
                order.Delivery = delivery;

                using (var uow = new DummyUnitOfWorkContainer())
                {
                    Assert.Throws <StateTransitionNotAllowedException>(() => uow.StateEngine.Execute(delivery, DeliveryState.Prepare));
                    uow.StateEngine.Execute(order, OrderState.Confirmed);
                    Assert.Throws <StateTransitionNotAllowedException>(() => uow.StateEngine.Execute(delivery, DeliveryState.Prepare));
                    uow.StateEngine.Execute(order, OrderState.Processing);
                    Assert.Throws <StateTransitionNotAllowedException>(() => uow.StateEngine.Execute(order, OrderState.Done));
                    uow.StateEngine.Execute(delivery, DeliveryState.Prepare);
                    Assert.Throws <StateTransitionNotAllowedException>(() => uow.StateEngine.Execute(order, OrderState.Done));
                    uow.StateEngine.Execute(delivery, DeliveryState.Sent);
                    Assert.Throws <StateTransitionNotAllowedException>(() => uow.StateEngine.Execute(order, OrderState.Done));
                    uow.StateEngine.Execute(delivery, DeliveryState.Done);
                    Assert.Equal(OrderState.Done, order.State);
                }
            }
        }
        public void StateEngineTest()
        {
            {
                // Setup page state
                var pageState = new StateDefinition <Page, PageStatus>(
                    x => x.Status,
                    new StateTransitionDefinition <Page, PageStatus>(PageStatus.Unpublished, PageStatusExtended.ForTranslation),
                    new StateTransitionDefinition <Page, PageStatus>(PageStatusExtended.ForTranslation, PageStatusExtended.ReadToPublish),
                    new StateTransitionDefinition <Page, PageStatus>(PageStatusExtended.ReadToPublish, PageStatus.Published),
                    new StateTransitionDefinition <Page, PageStatus>(PageStatusExtended.ReadToPublish, PageStatus.DeleyPublished)
                {
                    ExpectParameterType = typeof(DeleydPublishArgs),
                    Expect    = (page, o) => o.Date > DateTime.Now,
                    PreAction = (container, page, arg3) => page.TimePublishDate = arg3.Date
                }
                    );

                StateEngine.Add(pageState);
            }

            {
                // the actual test
                var page = new Page();

                using (var uow = new DummyUnitOfWorkContainer())
                {
                    Assert.Throws <StateTransitionNotAllowedException>(() => uow.StateEngine.Execute(page, PageStatus.Published));
                    Assert.Throws <StateTransitionNotAllowedException>(() => uow.StateEngine.Execute(page, PageStatusExtended.ReadToPublish));
                    uow.StateEngine.Execute(page, PageStatusExtended.ForTranslation);
                    Assert.Throws <StateTransitionNotAllowedException>(() => uow.StateEngine.Execute(page, PageStatus.Unpublished));
                    Assert.Throws <StateTransitionNotAllowedException>(() => uow.StateEngine.Execute(page, PageStatus.Published));
                    uow.StateEngine.Execute(page, PageStatusExtended.ReadToPublish);
                    Assert.Throws <StateTransitionNotAllowedException>(() => uow.StateEngine.Execute(page, PageStatus.Unpublished));
                    Assert.Throws <StateTransitionNotAllowedException>(() => uow.StateEngine.Execute(page, PageStatusExtended.ForTranslation));
                    Assert.Throws <StateTransitionNotAllowedException>(() => uow.StateEngine.Execute(page, PageStatusExtended.ReadToPublish));
                    uow.StateEngine.Execute(page, PageStatus.Published);
                }
            }

            Assert.Equal(PageStatus.Get("test"), PageStatus.Get("test"));
            Assert.Equal(PageStatus.Get("test"), PageStatus.Get("test"));
            Assert.Equal(PageStatus.Get("test"), PageStatus.Get("test"));
        }
        public void StateEngineTest()
        {
            var stateDefinition = new StateDefinition <TestEntity, TestStatus>(
                x => x.Status,
                new StateTransitionDefinition <TestEntity, TestStatus>(TestStatus.Status1, TestStatus.Status2),
                new StateTransitionDefinition <TestEntity, TestStatus>(TestStatus.Status2, TestStatus.Status3)
            {
                ExpectParameterType = typeof(StateChangeArgument),
                Expect    = (entity, o) => entity.Allow,
                PreAction = (container, entity, arg) =>
                {
                    /* do something before action */
                },
                PostAction = (container, entity, arg) =>
                {
                    entity.Date = arg.Date;
                    //container.OnCommitAction(() =>
                    //                            {
                    //                                // Code to send
                    //                            });
                    container.StateEngine.Execute(entity, TestStatus.Status4);
                }
            },
                new StateTransitionDefinition <TestEntity, TestStatus>(TestStatus.Status3, TestStatus.Status4),
                new StateTransitionDefinition <TestEntity, TestStatus>(TestStatus.Status4, TestStatus.Status5),
                new StateTransitionDefinition <TestEntity, TestStatus>(TestStatus.Status4, TestStatus.Status6));

            var testEntity          = new TestEntity();
            var stateChangeArgument = new StateChangeArgument {
                Date = DateTime.Now.AddDays(1)
            };

            using (var uow = new DummyUnitOfWorkContainer())
            {
                Assert.Equal(TestStatus.Status1, testEntity.Status);

                // state is not added and should throw state not found
                Assert.Throws <StateNotFoundForEntityException>(() => uow.StateEngine.Execute(testEntity, TestStatus.Status2));
            }

            // Add state definition to the static collection
            StateEngine.Add(stateDefinition);

            using (var uow = new DummyUnitOfWorkContainer())
            {
                Assert.Equal(TestStatus.Status1, testEntity.Status);

                var allowedStates = uow.StateEngine.GetAvailableTransitions <TestEntity, TestStatus>(testEntity);
                Assert.Equal(new HashSet <TestStatus>(new[] { TestStatus.Status2 }), allowedStates);

                Assert.Throws <StateTransitionArgumentException>(() => uow.StateEngine.Execute(testEntity, TestStatus.Status2, stateChangeArgument));
                Assert.Equal(TestStatus.Status1, testEntity.Status);

                uow.StateEngine.Execute(testEntity, TestStatus.Status2);
                Assert.Equal(TestStatus.Status2, testEntity.Status);

                allowedStates = uow.StateEngine.GetAvailableTransitions <TestEntity, TestStatus>(testEntity);
                Assert.Equal(new HashSet <TestStatus>(new[] { TestStatus.Status3 }), allowedStates);

                Assert.Throws <StateTransitionArgumentException>(() => uow.StateEngine.Execute(testEntity, TestStatus.Status3));
                Assert.Throws <StateTransitionNotAllowedException>(() => uow.StateEngine.Execute(testEntity, TestStatus.Status3, stateChangeArgument));
                Assert.Equal(TestStatus.Status2, testEntity.Status);

                testEntity.Allow = true;
                Assert.Throws <StateTransitionArgumentException>(() => uow.StateEngine.Execute(testEntity, TestStatus.Status3));
                Assert.Equal(TestStatus.Status2, testEntity.Status);

                uow.StateEngine.Execute(testEntity, TestStatus.Status3, stateChangeArgument);
                Assert.Equal(stateChangeArgument.Date, testEntity.Date);
                // Post action move status one more step so the status should be Status4
                Assert.Equal(TestStatus.Status4, testEntity.Status);

                allowedStates = uow.StateEngine.GetAvailableTransitions <TestEntity, TestStatus>(testEntity);
                Assert.Equal(new HashSet <TestStatus>(new[] { TestStatus.Status5, TestStatus.Status6 }), allowedStates);

                Assert.Throws <StateTransitionNotAllowedException>(() => uow.StateEngine.Execute(testEntity, TestStatus.Status1));
                Assert.Throws <StateTransitionNotAllowedException>(() => uow.StateEngine.Execute(testEntity, TestStatus.Status2));
            }
        }
Exemple #4
0
 public StateEngine(DummyUnitOfWorkContainer unitOfWork)
 {
     _unitOfWork = unitOfWork;
 }