public async Task HandlerShouldAddOrder()
        {
            // Arrange
            var expectedPlayer = new BrokerPlayer {
                PlayerId = Guid.NewGuid()
            };
            var expectedOrder = new BrokerOrder
            {
                OrderId = Guid.NewGuid(),
                ItemId  = Guid.NewGuid().ToString(),
            };

            _state.Players.Add(expectedPlayer.PlayerId, expectedPlayer);

            // Act
            await _handler.Handle(new OrderCreatedEvent(expectedOrder.OrderId, expectedPlayer)
            {
                ItemId = expectedOrder.ItemId,
            });

            // Assert
            Assert.Equal(expectedOrder.OrderId, _state.Orders.Values.Single().OrderId);
            Assert.Equal(expectedOrder.ItemId, _state.Orders.Values.Single().ItemId);
            Assert.Equal(OrderState.Active, _state.Orders.Values.Single().State);
            Assert.Same(expectedPlayer, _state.Orders.Values.Single().Owner);
        }
示例#2
0
        public async Task EvaluatorShouldFulfillOrders()
        {
            // Arrange
            var rng              = new Random();
            var givenState       = new State();
            var epxectedPrice    = rng.Next(1, 100);
            var expectedQuantity = rng.Next(1, 100);
            var expectedItem     = Guid.NewGuid().ToString();
            var buyer            = new BrokerPlayer {
                PlayerId = Guid.NewGuid(), Credits = epxectedPrice * expectedQuantity
            };
            var seller = new BrokerPlayer {
                PlayerId = Guid.NewGuid(), Inventory = CreateInventory(expectedItem, expectedQuantity)
            };
            var buyOrder  = CreateOrder(OrderType.Buy, expectedItem, buyer, epxectedPrice, expectedQuantity);
            var sellOrder = CreateOrder(OrderType.Sell, expectedItem, seller, epxectedPrice, expectedQuantity);

            givenState.Orders.Add(buyOrder.OrderId, buyOrder);
            givenState.Orders.Add(sellOrder.OrderId, sellOrder);

            // Act
            await _evaluator.Evaluate(givenState);

            // Assert
            Assert.Equal(OrderState.Fulfilled, buyOrder.State);
            Assert.Equal(OrderState.Fulfilled, sellOrder.State);
        }
示例#3
0
        public async Task HandlerShouldIgnoreOwnBalanceEvent()
        {
            // Arrange
            var expectedBalance = new Random().Next();
            var newBalance      = new Random().Next();
            var initialPlayer   = new BrokerPlayer
            {
                PlayerId = Guid.NewGuid(),
                Credits  = expectedBalance,
            };

            _state.Players.Add(initialPlayer.PlayerId, initialPlayer);

            // Act
            await _handler.Handle(new PlayerBalanceChangedEvent(initialPlayer.PlayerId, null)
            {
                BalanceChange = newBalance,
                Metadata      = new EventMetadata
                {
                    SourceAssembly = typeof(State).Assembly.FullName,
                },
            });

            // Assert
            Assert.Equal(expectedBalance, initialPlayer.Credits);
        }
示例#4
0
        public async Task HandlerShouldUpdateInventory()
        {
            // Arrange
            var expectedQuantity = new Random().Next();
            var expectedItem     = Guid.NewGuid().ToString();
            var initialPlayer    = new BrokerPlayer
            {
                PlayerId = Guid.NewGuid(),
            };

            _state.Players.Add(initialPlayer.PlayerId, initialPlayer);

            // Act
            await _handler.Handle(new PlayerInventoryChangedEvent(initialPlayer.PlayerId, null)
            {
                InventoryChange = new[]
                {
                    new LuaItemStack
                    {
                        Name  = expectedItem,
                        Count = expectedQuantity,
                    },
                },
            });

            // Assert
            Assert.Equal(expectedQuantity, initialPlayer.Inventory[expectedItem].Quantity);
        }
示例#5
0
        public async Task HandlerShouldIgnoreOwnInventoryEvent()
        {
            // Arrange
            var newQuantity   = new Random().Next();
            var newItem       = Guid.NewGuid().ToString();
            var initialPlayer = new BrokerPlayer
            {
                PlayerId = Guid.NewGuid(),
            };

            _state.Players.Add(initialPlayer.PlayerId, initialPlayer);

            // Act
            await _handler.Handle(new PlayerInventoryChangedEvent(initialPlayer.PlayerId, null)
            {
                InventoryChange = new[]
                {
                    new LuaItemStack
                    {
                        Name  = newItem,
                        Count = newQuantity,
                    },
                },
                Metadata = new EventMetadata
                {
                    SourceAssembly = typeof(State).Assembly.FullName,
                },
            });

            // Assert
            Assert.Empty(initialPlayer.Inventory);
        }
示例#6
0
        private bool TryUpdateInventory(BrokerPlayer player, BrokerShipment shipment)
        {
            LuaItemStack[] totalInventory;
            try
            {
                totalInventory = shipment.Carts.Reduce();
            } catch (InvalidOperationException e)
            {
                _logger.Error(e, $"Could not read inventory for shipment {shipment.ShipmentId}!");
                return(false);
            }

            foreach (var stack in totalInventory)
            {
                if (!player.Inventory.ContainsKey(stack.Name) || player.Inventory[stack.Name].Quantity < stack.Count)
                {
                    return(false);
                }
            }

            foreach (var stack in totalInventory)
            {
                player.Inventory[stack.Name].Quantity -= stack.Count;
            }

            return(true);
        }
        public async Task HandlerShouldFulfillShipment()
        {
            // Arrange
            var expectedItemId   = Guid.NewGuid().ToString();
            var expectedQuantity = new Random().Next();
            var expectedPlayer   = new BrokerPlayer {
                PlayerId = Guid.NewGuid(), Inventory = CreateInventory(expectedItemId, expectedQuantity)
            };
            var initialShipment = new BrokerShipment
            {
                ShipmentId         = Guid.NewGuid(),
                FactoryId          = Guid.NewGuid(),
                State              = ShipmentState.Requested,
                Owner              = expectedPlayer,
                WaitConditions     = CreateWaitConditions(),
                DestinationStation = Guid.NewGuid().ToString(),
                Carts              = CreateCartContents(expectedItemId, expectedQuantity),
            };

            _state.Shipments.Add(initialShipment.ShipmentId, initialShipment);

            // Act
            await _handler.Handle(new ShipmentFulfilledEvent(initialShipment.ShipmentId, initialShipment.FactoryId, expectedPlayer));

            // Assert
            Assert.Equal(ShipmentState.Fulfilled, initialShipment.State);
            Assert.Equal(0, expectedPlayer.Inventory.Values.Single().Quantity);
        }
        public async Task HandlerShouldAddShipment()
        {
            // Arrange
            var expectedItemId   = Guid.NewGuid().ToString();
            var expectedQuantity = new Random().Next();
            var expectedPlayer   = new BrokerPlayer {
                PlayerId = Guid.NewGuid()
            };
            var expectedShipment = new BrokerShipment
            {
                ShipmentId         = Guid.NewGuid(),
                FactoryId          = Guid.NewGuid(),
                OwnerId            = expectedPlayer.PlayerId,
                WaitConditions     = CreateWaitConditions(),
                DestinationStation = Guid.NewGuid().ToString(),
                Carts = CreateCartContents(expectedItemId, expectedQuantity),
            };

            _state.Players.Add(expectedPlayer.PlayerId, expectedPlayer);

            // Act
            await _handler.Handle(new ShipmentRequestedEvent(expectedShipment.ShipmentId, expectedShipment.FactoryId, expectedPlayer)
            {
                Carts              = expectedShipment.Carts.ToArray(),
                WaitConditions     = expectedShipment.WaitConditions.ToArray(),
                DestinationStation = expectedShipment.DestinationStation,
                OwnerId            = expectedShipment.OwnerId,
            });

            // Assert
            Assert.Equal(expectedShipment.ShipmentId, _state.Shipments.Values.Single().ShipmentId);
            Assert.Equal(expectedShipment.FactoryId, _state.Shipments.Values.Single().FactoryId);
            Assert.Equal(ShipmentState.Requested, _state.Shipments.Values.Single().State);
            Assert.Same(expectedPlayer, _state.Shipments.Values.Single().Owner);
        }
示例#9
0
        public async Task EvaluatorShouldFulfillShipments()
        {
            // Arrange
            var rng              = new Random();
            var givenState       = new State();
            var expectedQuantity = rng.Next(1, 100);
            var expectedItem     = Guid.NewGuid().ToString();
            var owner            = new BrokerPlayer
            {
                Inventory = new Dictionary <string, WarehouseInventory>
                {
                    { expectedItem, new WarehouseInventory {
                          Quantity = expectedQuantity
                      } }
                }
            };
            var shipment = new BrokerShipment
            {
                Owner      = owner,
                ShipmentId = Guid.NewGuid(),
                FactoryId  = Guid.NewGuid(),
                State      = ShipmentState.Requested,
                Carts      = new[]
                {
                    new Cart
                    {
                        CartType  = CartType.Cargo,
                        Inventory = new[]
                        {
                            new LuaItemStack
                            {
                                Name  = expectedItem,
                                Count = expectedQuantity,
                            },
                        },
                    },
                },
            };

            givenState.Shipments.Add(shipment.ShipmentId, shipment);

            // Act
            var result = await _evaluator.Evaluate(givenState);

            // Assert
            Assert.NotEmpty(result);

            // Inventory reduced?
            Assert.Equal(0, owner.Inventory[expectedItem].Quantity);
            Assert.Equal(-expectedQuantity, result.OfType <PlayerInventoryChangedEvent>().Single().InventoryChange.Single().Count);

            // Shipment fulfilled?
            var evnt = result.OfType <ShipmentFulfilledEvent>().Single();

            Assert.Equal(shipment.ShipmentId, evnt.EntityId);
            Assert.Equal(shipment.FactoryId, evnt.FactoryId);
        }
示例#10
0
 private BrokerOrder CreateOrder(OrderType type, string itemId, BrokerPlayer owner, int price, int quantity = -1)
 {
     return(new BrokerOrder
     {
         OrderId = Guid.NewGuid(),
         OrderType = type,
         ItemId = itemId,
         Owner = owner,
         Quantity = quantity,
         Price = price,
         State = OrderState.Active,
     });
 }
        public async Task HandlerShouldAddFactoryOwner()
        {
            // Arrange
            var expectedFactoryId = Guid.NewGuid();
            var expectedOwner     = new BrokerPlayer
            {
                PlayerId = Guid.NewGuid(),
            };

            _state.Players.Add(expectedOwner.PlayerId, expectedOwner);

            // Act
            await _handler.Handle(new FactoryCreatedEvent(expectedFactoryId, default, expectedOwner));
示例#12
0
 private void UpdatePlayerInventory(BrokerPlayer player, string itemId, long quantity)
 {
     if (player.Inventory.TryGetValue(itemId, out var inventory))
     {
         inventory.Quantity += quantity;
     }
     else
     {
         player.Inventory.Add(itemId, new WarehouseInventory
         {
             ItemId   = itemId,
             Quantity = quantity,
         });
     }
 }
示例#13
0
        public async Task HandlerShouldUpdateBalance()
        {
            // Arrange
            var expectedBalance = new Random().Next();
            var initialPlayer   = new BrokerPlayer
            {
                PlayerId = Guid.NewGuid(),
            };

            _state.Players.Add(initialPlayer.PlayerId, initialPlayer);

            // Act
            await _handler.Handle(new PlayerBalanceChangedEvent(initialPlayer.PlayerId, null)
            {
                BalanceChange = expectedBalance,
            });

            // Assert
            Assert.Equal(expectedBalance, initialPlayer.Credits);
        }
示例#14
0
        public async Task EvaluatorShouldMatchOrders()
        {
            // Arrange
            var rng              = new Random();
            var givenState       = new State();
            var epxectedPrice    = rng.Next(1, 100);
            var expectedQuantity = rng.Next(1, 100);
            var expectedItem     = Guid.NewGuid().ToString();
            var buyer            = new BrokerPlayer {
                PlayerId = Guid.NewGuid(), Credits = epxectedPrice * expectedQuantity
            };
            var seller = new BrokerPlayer {
                PlayerId = Guid.NewGuid(), Inventory = CreateInventory(expectedItem, expectedQuantity)
            };
            var buyOrder  = CreateOrder(OrderType.Buy, expectedItem, buyer, epxectedPrice);
            var sellOrder = CreateOrder(OrderType.Sell, expectedItem, seller, epxectedPrice);

            givenState.Orders.Add(buyOrder.OrderId, buyOrder);
            givenState.Orders.Add(sellOrder.OrderId, sellOrder);

            // Act
            var result = await _evaluator.Evaluate(givenState);

            // Assert
            Assert.NotEmpty(result);

            // Credits transferred?
            Assert.Equal(0, buyer.Credits);
            Assert.Equal(epxectedPrice * expectedQuantity, seller.Credits);

            // Inventory transferred?
            Assert.Equal(0, seller.Inventory.Values.Single().Quantity);
            Assert.Equal(expectedQuantity, buyer.Inventory.Values.Single().Quantity);

            // Order updated?
            Assert.Equal(expectedQuantity, buyOrder.QuantityFulfilled);
            Assert.Equal(expectedQuantity, sellOrder.QuantityFulfilled);
        }
        public async Task HandlerShouldHandleTransaction(bool buyerHasExistingInventory)
        {
            // Arrange
            var rng              = new Random();
            var expectedPrice    = rng.Next();
            var expectedQuantity = rng.Next();
            var expectedItem     = Guid.NewGuid().ToString();
            var buyer            = new BrokerPlayer
            {
                PlayerId  = Guid.NewGuid(),
                Inventory = new Dictionary <string, WarehouseInventory>(),
            };

            if (buyerHasExistingInventory)
            {
                buyer.Inventory.Add(expectedItem, new WarehouseInventory());
            }
            var seller = new BrokerPlayer
            {
                PlayerId  = Guid.NewGuid(),
                Inventory = new Dictionary <string, WarehouseInventory>
                {
                    { expectedItem, new WarehouseInventory() }
                }
            };
            var buyOrder = new BrokerOrder
            {
                OrderId   = Guid.NewGuid(),
                OrderType = OrderType.Buy,
                ItemId    = expectedItem,
                Owner     = buyer,
            };
            var sellOrder = new BrokerOrder
            {
                OrderId   = Guid.NewGuid(),
                OrderType = OrderType.Sell,
                ItemId    = expectedItem,
                Owner     = seller,
            };

            _state.Orders.Add(buyOrder.OrderId, buyOrder);
            _state.Orders.Add(sellOrder.OrderId, sellOrder);

            // Act
            await _handler.Handle(new OrderTransactionEvent(Guid.NewGuid(), null)
            {
                FromSellOrder = sellOrder.OrderId,
                ToBuyOrder    = buyOrder.OrderId,
                Quantity      = expectedQuantity,
                Price         = expectedPrice,
                ItemId        = expectedItem,
            });

            // Assert
            Assert.Equal(-expectedPrice, buyer.Credits);
            Assert.Equal(expectedPrice, seller.Credits);
            Assert.Equal(expectedQuantity, buyOrder.QuantityFulfilled);
            Assert.Equal(expectedQuantity, sellOrder.QuantityFulfilled);
            Assert.Equal(expectedQuantity, buyer.Inventory[expectedItem].Quantity);
            Assert.Equal(-expectedQuantity, seller.Inventory[expectedItem].Quantity);
        }