Inheritance: Actor, ICustomerOrderActor, IRemindable
        public async Task TestFulfillOrderWithBackorder()
        {
            // instruct the mock inventory service to always return less quantity than requested 
            // so that FulfillOrder always ends up in backordered status.            

            MockInventoryService inventoryService = new MockInventoryService()
            {
                RemoveStockAsyncFunc = (itemId, quantity, cmid) => Task.FromResult(quantity - 1)
            };

            MockServiceProxy serviceProxy = new MockServiceProxy();
            serviceProxy.Supports<IInventoryService>(serviceUri => inventoryService);

            CustomerOrderActor target = new CustomerOrderActor();

            PropertyInfo idProperty = typeof(ActorBase).GetProperty("Id");
            idProperty.SetValue(target, new ActorId(Guid.NewGuid()));

            target.ServiceProxy = serviceProxy;
            await target.StateManager.SetStateAsync<CustomerOrderStatus>(RequestIdPropertyName, CustomerOrderStatus.Submitted);
            await target.StateManager.SetStateAsync<long>(RequestIdPropertyName, 0);
            await target.StateManager.SetStateAsync<List<CustomerOrderItem>>(OrderItemListPropertyName, new List<CustomerOrderItem>()
            {
                new CustomerOrderItem(new InventoryItemId(), 4)
            });

            await target.FulfillOrderAsync();

            Assert.AreEqual<CustomerOrderStatus>(CustomerOrderStatus.Backordered, await target.StateManager.GetStateAsync<CustomerOrderStatus>(OrderStatusPropertyName));
        }
        public async Task TestFulfillOrderSimple()
        {
            // The default mock inventory service behavior is to always complete an order.
            MockInventoryService inventoryService = new MockInventoryService();

            MockServiceProxy serviceProxy = new MockServiceProxy();
            serviceProxy.Supports<IInventoryService>(serviceUri => inventoryService);

            CustomerOrderActor target = new CustomerOrderActor();

            PropertyInfo idProperty = typeof(Actor).GetProperty("Id");
            idProperty.SetValue(target, new ActorId(Guid.NewGuid()));

            target.ServiceProxy = serviceProxy;

            await target.StateManager.SetStateAsync<CustomerOrderStatus>(RequestIdPropertyName, CustomerOrderStatus.Submitted);
            await target.StateManager.SetStateAsync<long>(RequestIdPropertyName, 0);
            await target.StateManager.SetStateAsync<List<CustomerOrderItem>>(OrderItemListPropertyName, new List<CustomerOrderItem>()
            {
                new CustomerOrderItem(new InventoryItemId(), 4)
            });

            await target.FulfillOrderAsync();

            Assert.AreEqual<CustomerOrderStatus>(CustomerOrderStatus.Shipped, await target.StateManager.GetStateAsync<CustomerOrderStatus>(OrderStatusPropertyName));
        }
        public async Task TestFulfillOrderSimple()
        {
            // The default mock inventory service behavior is to always complete an order.
            MockInventoryService inventoryService = new MockInventoryService();

            MockServiceProxy serviceProxy = new MockServiceProxy();
            serviceProxy.Supports<IInventoryService>(serviceUri => inventoryService);

            CustomerOrderActor target = new CustomerOrderActor();

            PropertyInfo idProperty = typeof(ActorBase).GetProperty("Id");
            idProperty.SetValue(target, new ActorId(Guid.NewGuid()));

            target.ServiceProxy = serviceProxy;
            target.State = new CustomerOrderActorState();

            target.State.Status = CustomerOrderStatus.Submitted;
            target.State.OrderedItems = new List<CustomerOrderItem>()
            {
                new CustomerOrderItem(new InventoryItemId(), 4)
            };

            await target.FulfillOrderAsync();

            Assert.AreEqual<CustomerOrderStatus>(CustomerOrderStatus.Shipped, target.State.Status);
        }
        public async Task TestFulfillOrderToCompletion()
        {
            int itemCount = 5;

            // instruct the mock inventory service to only fulfill one item each time
            // so that FulfillOrder has to make multiple iterations to complete an order
            MockInventoryService inventoryService = new MockInventoryService()
            {
                RemoveStockAsyncFunc = (itemId, quantity, cmid) => Task.FromResult(1)
            };

            MockServiceProxy serviceProxy = new MockServiceProxy();
            serviceProxy.Supports<IInventoryService>(serviceUri => inventoryService);

            CustomerOrderActor target = new CustomerOrderActor();

            PropertyInfo idProperty = typeof(ActorBase).GetProperty("Id");
            idProperty.SetValue(target, new ActorId(Guid.NewGuid()));

            target.ServiceProxy = serviceProxy;
            await target.StateManager.SetStateAsync<CustomerOrderStatus>(RequestIdPropertyName, CustomerOrderStatus.Submitted);
            await target.StateManager.SetStateAsync<long>(RequestIdPropertyName, 0);
            await target.StateManager.SetStateAsync<List<CustomerOrderItem>>(OrderItemListPropertyName, new List<CustomerOrderItem>()
            {
                new CustomerOrderItem(new InventoryItemId(), 4)
            });

            for (int i = 0; i < itemCount - 1; ++i)
            {
                await target.FulfillOrderAsync();
                Assert.AreEqual<CustomerOrderStatus>(CustomerOrderStatus.Backordered, await target.StateManager.GetStateAsync<CustomerOrderStatus>(OrderStatusPropertyName));
            }

            await target.FulfillOrderAsync();
            Assert.AreEqual<CustomerOrderStatus>(CustomerOrderStatus.Shipped, await target.StateManager.GetStateAsync<CustomerOrderStatus>(OrderStatusPropertyName));
        }
        public async Task TestFulfillOrderCancelled()
        {
            // instruct the mock inventory service to return 0 for all items to simulate items that don't exist.
            // and have it return false when asked if an item exists to make sure FulfillOrder doesn't get into
            // an infinite backorder loop.
            MockInventoryService inventoryService = new MockInventoryService()
            {
                IsItemInInventoryAsyncFunc = itemId => Task.FromResult(false),
                RemoveStockAsyncFunc = (itemId, quantity, cmid) => Task.FromResult(0)
            };


            MockServiceProxy serviceProxy = new MockServiceProxy();
            serviceProxy.Supports<IInventoryService>(serviceUri => inventoryService);

            CustomerOrderActor target = new CustomerOrderActor();

            PropertyInfo idProperty = typeof(ActorBase).GetProperty("Id");
            idProperty.SetValue(target, new ActorId(Guid.NewGuid()));

            target.ServiceProxy = serviceProxy;
            await target.StateManager.SetStateAsync<CustomerOrderStatus>(RequestIdPropertyName, CustomerOrderStatus.Submitted);
            await target.StateManager.SetStateAsync<long>(RequestIdPropertyName, 0);
            await target.StateManager.SetStateAsync<List<CustomerOrderItem>>(OrderItemListPropertyName, new List<CustomerOrderItem>()
            {
                new CustomerOrderItem(new InventoryItemId(), 5)
            });

            await target.FulfillOrderAsync();

            Assert.AreEqual<CustomerOrderStatus>(CustomerOrderStatus.Canceled, await target.StateManager.GetStateAsync<CustomerOrderStatus>(OrderStatusPropertyName));
        }
        private static async Task<CustomerOrderActor> CreateCustomerOrderActor(MockServiceProxyFactory serviceProxyFactory)
        {
            try
            {
                CustomerOrderActor target = new CustomerOrderActor(
                    new ActorService(
                        context: statefulServiceContext,
                        actorTypeInfo: ActorTypeInformation.Get(typeof(CustomerOrderActor)),
                        stateManagerFactory: (actorBase, stateProvider) => new MockActorStateManager()),
                    new ActorId(Guid.NewGuid()));

                await target.InternalActivateAsync(codePackageContext, serviceProxyFactory);

                return target;
            }
            catch (Exception e)
            {
                throw;
            }
        }