public void Should_throw_on_set_state_to_null()
        {
            var process = new PizzaFulfillmentProcess();

            Should.Throw <InvalidOperationException>(
                () => process.SetState(null)
                );
        }
        public void Should_leave_current_state_null_when_set_state_with_null()
        {
            var process = new PizzaFulfillmentProcess();

            process.SetState(new PizzaFulfillmentState()
            {
                CurrentState = null
            });
            process.State.CurrentState.ShouldBeNull();
        }
        public void Should_throw_on_set_state_with_invalid_state_string()
        {
            var process = new PizzaFulfillmentProcess();

            Should.Throw <Exception>(
                () => process.SetState(new PizzaFulfillmentState()
            {
                CurrentState = "InvalidStateName"
            })
                );
        }
        public async Task Should_transition_on_message_to_completion()
        {
            var process = new PizzaFulfillmentProcess();

            process.SetState(new PizzaFulfillmentState()
            {
                CurrentState = "Ordered"
            });
            process.State.CurrentState.ShouldBe("Ordered");

            var prepareDate = DateTime.UtcNow;
            await process.Handle(new PizzaPreparedEvent()
            {
                PreparedAt = prepareDate
            }, _fixture.FakeContext);

            process.State.CurrentState.ShouldBe("Ordered");
            process.State.PreparedAtUtc.ShouldBe(prepareDate);

            var payDate = DateTime.UtcNow;
            await process.Handle(new PizzaPaidForEvent()
            {
                PaidAt = payDate
            }, _fixture.FakeContext);

            process.State.CurrentState.ShouldBe("Ready");
            process.State.PaidAtUtc.ShouldBe(payDate);

            var shipDate = DateTime.UtcNow;
            await process.Handle(new PizzaShippedEvent()
            {
                ShippedAt = shipDate
            }, _fixture.FakeContext);

            process.State.CurrentState.ShouldBe("OutForDelivery");
            process.State.ShippedAtUtc.ShouldBe(shipDate);

            var deliverDate = DateTime.UtcNow;
            await process.Handle(new PizzaDeliveredEvent()
            {
                DeliveredAt = deliverDate
            }, _fixture.FakeContext);

            process.State.CurrentState.ShouldBe("Complete");
            process.State.DeliveredAtUtc.ShouldBe(deliverDate);
            process.State.CompletedAtUtc.Value.ShouldBeGreaterThan(deliverDate);
        }
        public void Should_throw_on_message_with_no_handler_in_state()
        {
            var process = new PizzaFulfillmentProcess();

            process.SetState(new PizzaFulfillmentState()
            {
                CurrentState = "Ordered"
            });
            Should.Throw <InvalidMessageForStateException>(
                () => process.Handle(
                    new PizzaDeliveredEvent()
            {
                DeliveredAt = DateTime.UtcNow
            },
                    _fixture.FakeContext)
                );
        }
        public void Should_not_instantiate_state_on_new()
        {
            var process = new PizzaFulfillmentProcess();

            process.State.ShouldBeNull();
        }