FulfillOrderAsync() private method

This method takes in a list of CustomerOrderItem objects. Using a Service Proxy to access the Inventory Service, the method iterates onces through the order and tries to remove the quantity specified in the order from inventory. If the inventory has insufficient stock to remove the requested amount for a particular item, the entire order is marked as backordered and the item in question is added to a "backordered" item list, which is fulfilled in a separate method. In its current form, this application addresses the question of race conditions to remove the same item by making a rule that no order ever fails. While an item that is displayed in the store may not be available any longer by the time an order is placed, the automatic restock policy instituted in the Inventory Service means that our FulfillOrder method and its sub-methods can continue to query the Inventory Service on repeat (with a timer in between each cycle) until the order is fulfilled.
private FulfillOrderAsync ( ) : Task
return Task
        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 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;
            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.Backordered, target.State.Status);
        }
        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));
        }