public async Task When_getting_all_shipping_lines()
        {
            using (var contextFactory = new FakeShipRegistryContextFactory(_options))
            {
                //arrange
                var uow        = contextFactory.Create();
                var repository = new ShippingLineRepositoryAsync(uow);

                var existingLineOne = new ShippingLine(new Id(), new LineName("Maersk"));
                await repository.AddAsync(existingLineOne);

                var existingLineTwo = new ShippingLine(new Id(), new LineName("Onassis"));
                await repository.AddAsync(existingLineTwo);

                var query        = new ShippingLinesAllQuery();
                var queryHandler = new ShippingLinesAllQueryHandler(contextFactory);

                //act
                var lines = await queryHandler.ExecuteAsync(query);

                //assert
                Assert.That(lines, Is.Not.Null);
                Assert.That(2, Is.EqualTo(lines.ShippingLines.Length));
            }
        }
        public async Task When_registering_a_new_shipping_line()
        {
            using (var contextFactory = new FakeShipRegistryContextFactory(_options))
            {
                //arrange
                var commandProcessor = new FakeCommandProcessor();

                var newShippingLineCommand = new AddShippingLineCommand(new LineName("Maersk"));
                var handler = new NewShippingLineHandlerAsync(contextFactory, commandProcessor);

                //act
                await handler.HandleAsync(newShippingLineCommand);

                //assert
                var uow  = contextFactory.Create();
                var line = uow.Lines.SingleOrDefault(l => l.Id == new Id(newShippingLineCommand.Id));

                Assert.That(line, Is.Not.Null);
                Assert.That(line.Id, Is.EqualTo(new Id(newShippingLineCommand.Id)));
                Assert.That(line.LineName, Is.EqualTo(newShippingLineCommand.LineName));

                var domainEvent = commandProcessor.Messages.SingleOrDefault(m => m.Action == Action.Post);
                Assert.That(domainEvent, Is.Not.Null);

                var addedMessage = (NewLineAddedEvent)domainEvent.Message;
                Assert.That(addedMessage, Is.Not.Null);
                Assert.That(addedMessage.LineId, Is.EqualTo(new Id(newShippingLineCommand.Id)));
                Assert.That(addedMessage.LineName, Is.EqualTo(newShippingLineCommand.LineName));
            }
        }
        public async Task When_updating_a_shipping_line_name()
        {
            using (var contextFactory = new FakeShipRegistryContextFactory(_options))
            {
                //arrange
                var uow          = contextFactory.Create();
                var repository   = new ShippingLineRepositoryAsync(uow);
                var existingLine = new ShippingLine(new Id(), new LineName("Maersk"));
                await repository.AddAsync(existingLine);

                var commandProcessor = new FakeCommandProcessor();

                var command = new UpdateLineNameCommand(existingLine.Id, new LineName("Onassis"));

                var handler = new UpdateLineNameHandler(contextFactory, commandProcessor);

                //act
                await handler.HandleAsync(command);

                //assert
                var line = uow.Lines.SingleOrDefault(l => l.Id == existingLine.Id);
                Assert.That(line.LineName, Is.EqualTo(new LineName("Onassis")));
                Assert.That(line.Version, Is.EqualTo(1));

                var domainEvent = commandProcessor.Messages.SingleOrDefault(m => m.Action == Action.Post);
                Assert.That(domainEvent, Is.Not.Null);

                var addedMessage = (LineNameUpdatedEvent)domainEvent.Message;
                Assert.That(addedMessage.LineName, Is.EqualTo(new LineName("Onassis")));
                Assert.That(addedMessage.Version, Is.EqualTo(1));
            }
        }
        public async Task When_getting_a_ship()
        {
            //arrange
            using (var contextFactory = new FakeShipRegistryContextFactory(_options))
            {
                var uow        = contextFactory.Create();
                var repository = new ShipRepositoryAsync(uow);
                var ship       = new Ship(new Id(), new ShipName("Majestic"), ShipType.Container, new Capacity(50000), new Id());

                await repository.AddAsync(ship);

                var query = new ShipByIdQuery(ship.Id);

                var queryHandler = new ShipByIdQueryHandlerAsync(contextFactory);

                //act
                var foundShip = await queryHandler.ExecuteAsync(query);

                //asert
                Assert.That(foundShip.Id, Is.EqualTo(ship.Id.Value));
                Assert.That(foundShip.Capacity, Is.EqualTo(ship.Capacity.Value));
                Assert.That(foundShip.ShipName, Is.EqualTo(ship.ShipName.ToString()));
                Assert.That(foundShip.ShipType, Is.EqualTo(ship.ShipType.ToString()));
                Assert.That(foundShip.ShippingLineId, Is.EqualTo(ship.ShippingLineId.Value));
            }
        }
        public async Task When_removing_a_ship_registration()
        {
            //arrange
            using (var contextFactory = new FakeShipRegistryContextFactory(_options))
            {
                var uow        = contextFactory.Create();
                var repository = new ShipRepositoryAsync(uow);
                var ship       = new Ship(new Id(), new ShipName("Majestic"), ShipType.Container, new Capacity(50000), new Id());

                await repository.AddAsync(ship);

                var commandProcessor = new FakeCommandProcessor();

                var command = new RemoveShipCommand(ship.Id);

                var handler = new RemoveShipHandlerAsync(contextFactory, commandProcessor);

                //act
                await handler.HandleAsync(command);

                //assert
                var removedShip = await uow.Ships.SingleOrDefaultAsync(s => s.Id == ship.Id);

                Assert.That(removedShip, Is.Null);

                var domainEvent = commandProcessor.Messages.SingleOrDefault(m => m.Action == Action.Post);
                Assert.That(domainEvent, Is.Not.Null);

                var shipRemovedEvent = (ShipRemovedEvent)domainEvent.Message;
                Assert.That(shipRemovedEvent.ShipRemoved, Is.EqualTo(ship.Id));
            }
        }
        public async Task When_getting_all_ships()
        {
            //arrange
            using (var contextFactory = new FakeShipRegistryContextFactory(_options))
            {
                var uow        = contextFactory.Create();
                var repository = new ShipRepositoryAsync(uow);
                var shipOne    = new Ship(new Id(), new ShipName("Majestic"), ShipType.Container, new Capacity(50000), new Id());
                var shipTwo    = new Ship(new Id(), new ShipName("Royal"), ShipType.Container, new Capacity(80000), new Id());

                await repository.AddAsync(shipOne);

                await repository.AddAsync(shipTwo);

                var query = new ShipsAllQuery();

                var queryHandler = new ShipsAllQueryHandlerAsync(contextFactory);

                //act
                var result = await queryHandler.ExecuteAsync(query);

                //asert
                Assert.That(2, Is.EqualTo(result.Ships.Length));
            }
        }
        public async Task When_registering_a_new_ship()
        {
            //arrange
            using (var contextFactory = new FakeShipRegistryContextFactory(_options))
            {
                var uow = contextFactory.Create();

                var lineRepo = new ShippingLineRepositoryAsync(uow);

                var shippingLine = lineRepo.AddAsync(new ShippingLine(new Id(), new LineName("Maersk"))).Result;

                var commandProcessor = new FakeCommandProcessor();

                var handler = new NewShipRegistrationHandlerAsync(contextFactory, commandProcessor);

                var newShipCommand = new AddShipCommand(
                    type: ShipType.Tanker,
                    name: new ShipName("MV Toronto Star"),
                    capacity: new Capacity(30000),
                    shippingLine: shippingLine.Id);

                //act
                await handler.HandleAsync(newShipCommand);

                //assert
                var ship = uow.Ships.SingleOrDefault(s => s.Id == new Id(newShipCommand.Id));
                Assert.That(ship, Is.Not.Null);
                Assert.That(ship.ShipType, Is.EqualTo(newShipCommand.Type));
                Assert.That(ship.ShipName, Is.EqualTo(newShipCommand.Name));
                Assert.That(ship.Capacity, Is.EqualTo(newShipCommand.Capacity));
                Assert.That(ship.Id, Is.EqualTo(new Id(newShipCommand.Id)));
                Assert.That(ship.ShippingLineId, Is.EqualTo(newShipCommand.ShippingLine));
                Assert.That(ship.Version, Is.EqualTo(0));

                var domainEvent = commandProcessor.Messages.SingleOrDefault(m => m.Action == Action.Post);
                Assert.That(domainEvent, Is.Not.Null);

                var addedMessage = (NewShipAddedEvent)domainEvent.Message;
                Assert.That(addedMessage.Id, Is.EqualTo(newShipCommand.Id));
                Assert.That(addedMessage.Capacity, Is.EqualTo(newShipCommand.Capacity));
                Assert.That(addedMessage.Name, Is.EqualTo(newShipCommand.Name));
                Assert.That(addedMessage.Type, Is.EqualTo(newShipCommand.Type));
                Assert.That(addedMessage.ShipId, Is.EqualTo(new Id(newShipCommand.Id)));
                Assert.That(addedMessage.ShippingLine, Is.EqualTo(newShipCommand.ShippingLine));
            }
        }
        public async Task When_getting_a_shipping_line()
        {
            using (var contextFactory = new FakeShipRegistryContextFactory(_options))
            {
                //arrange
                var uow          = contextFactory.Create();
                var repository   = new ShippingLineRepositoryAsync(uow);
                var existingLine = new ShippingLine(new Id(), new LineName("Maersk"));
                await repository.AddAsync(existingLine);

                var query        = new ShippingLineByIdQuery(existingLine.Id);
                var queryHandler = new ShippingLineByIdQueryHandler(contextFactory);

                //act
                var line = await queryHandler.ExecuteAsync(query);

                //assert
                Assert.That(line, Is.Not.Null);
                Assert.That(line.Id, Is.EqualTo(existingLine.Id.Value));
                Assert.That(line.LineName, Is.EqualTo(existingLine.LineName.ToString()));
            }
        }
        public async Task When_removing_a_shipping_line()
        {
            using (var contextFactory = new FakeShipRegistryContextFactory(_options))
            {
                //arrange
                var uow          = contextFactory.Create();
                var repository   = new ShippingLineRepositoryAsync(uow);
                var existingLine = new ShippingLine(new Id(), new LineName("Maersk"));
                await repository.AddAsync(existingLine);

                var command = new RemoveLineCommand(existingLine.Id);

                var handler = new RemoveLineHandlerAsync(contextFactory);

                //act
                await handler.HandleAsync(command);

                //assert
                var line = uow.Lines.SingleOrDefault(l => l.Id == existingLine.Id);
                Assert.That(line, Is.Null);
            }
        }
        public async Task When_updating_an_existing_ship_name()
        {
            //arrange
            using (var contextFactory = new FakeShipRegistryContextFactory(_options))
            {
                var uow        = contextFactory.Create();
                var repository = new ShipRepositoryAsync(uow);
                var ship       = new Ship(new Id(), new ShipName("Majestic"), ShipType.Container, new Capacity(50000), new Id());

                await repository.AddAsync(ship);

                var commandProcessor = new FakeCommandProcessor();

                var command = new UpdateShipNameCommand(ship.Id, name: new ShipName("Toronto Star"));

                var handler = new UpdateShipNameHandlerAsync(contextFactory, commandProcessor);

                //act
                await handler.HandleAsync(command);

                //assert
                var updatedShip = await uow.Ships.SingleOrDefaultAsync(s => s.Id == ship.Id);

                Assert.That(updatedShip, Is.Not.Null);
                Assert.That(updatedShip.ShipName, Is.EqualTo(command.Name));
                Assert.That(updatedShip.Version, Is.EqualTo(1));
                Assert.That(ship.Version, Is.EqualTo(1));

                var domainEvent = commandProcessor.Messages.SingleOrDefault(m => m.Action == Action.Post);
                Assert.That(domainEvent, Is.Not.Null);

                var updatedNameMessage = (ShipNameUpdatedEvent)domainEvent.Message;
                Assert.That(updatedNameMessage.ShipId, Is.EqualTo(updatedShip.Id));
                Assert.That(updatedNameMessage.ShipName, Is.EqualTo(updatedShip.ShipName));
                Assert.That(updatedNameMessage.Version, Is.EqualTo(1));
            }
        }