public async Task SetsCorrectCacheEntry_WhenOptimizeRouteResultIsSuccess_AndRequestOrderIsUpdated()
        {
            var optimizeRouteService = new Mock <IOptimizeRouteService>();

            optimizeRouteService.Setup(x => x.OptimizeRoute(It.IsAny <OptimizeRouteCriteria>()))
            .ReturnsAsync(new OptimizeRouteResult {
                Distance = 10, Duration = 10, RequestIds = new List <Guid> {
                    Request4Id, Request1Id
                }
            });

            var cache = new MemoryCache(new MemoryCacheOptions());

            var sut = new OptimizeRouteCommandHandler(Context, optimizeRouteService.Object, cache);

            await sut.Handle(new OptimizeRouteCommand { ItineraryId = 1, UserId = "123" });

            var expectedCacheKey = CacheKeyBuilder.BuildOptimizeRouteCacheKey("123", 1);

            OptimizeRouteResultStatus cachedStatus = null;
            var keyExists = cache.TryGetValue(expectedCacheKey, out cachedStatus);

            keyExists.ShouldBeTrue();
            cachedStatus.IsSuccess.ShouldBeTrue();
            cachedStatus.StatusMessage.ShouldBe(OptimizeRouteStatusMessages.OptimizeSucess);
        }
        public async Task NotCallOptimizeRouteService_WhenItineraryHasNoEndAddress_AndNotSetToUseStartAddressAsEndAddress()
        {
            var optimizeRouteService = new Mock <IOptimizeRouteService>();

            optimizeRouteService.Setup(x => x.OptimizeRoute(It.IsAny <OptimizeRouteCriteria>())).Verifiable();

            var sut = new OptimizeRouteCommandHandler(Context, optimizeRouteService.Object, Mock.Of <IMemoryCache>());

            await sut.Handle(new OptimizeRouteCommand { ItineraryId = 3 });

            optimizeRouteService.Verify(x => x.OptimizeRoute(It.IsAny <OptimizeRouteCriteria>()), Times.Never);
        }
        public async Task NotCallOptimizeRouteService_WhenItineraryNotFound()
        {
            var optimizeRouteService = new Mock <IOptimizeRouteService>();

            optimizeRouteService.Setup(x => x.OptimizeRoute(It.IsAny <OptimizeRouteCriteria>())).Verifiable();

            var sut = new OptimizeRouteCommandHandler(Context, optimizeRouteService.Object, Mock.Of <IMemoryCache>());

            await sut.Handle(new OptimizeRouteCommand { ItineraryId = 200 });

            optimizeRouteService.Verify(x => x.OptimizeRoute(It.IsAny <OptimizeRouteCriteria>()), Times.Never);
        }
        public async Task NotChangeRequestOrder_WhenOptimizeRouteResultIsNotSuccess()
        {
            var optimizeRouteService = new Mock <IOptimizeRouteService>();

            optimizeRouteService.Setup(x => x.OptimizeRoute(It.IsAny <OptimizeRouteCriteria>()))
            .ReturnsAsync(OptimizeRouteResult.FailedOptimizeRouteResult("failure"));

            var sut = new OptimizeRouteCommandHandler(Context, optimizeRouteService.Object, Mock.Of <IMemoryCache>());

            await sut.Handle(new OptimizeRouteCommand { ItineraryId = 1 });

            var requests = Context.ItineraryRequests.Where(x => x.ItineraryId == 1).OrderBy(x => x.OrderIndex).ToList();

            requests[0].Request.Name.ShouldBe("Request 1");
            requests[1].Request.Name.ShouldBe("Request 4");
        }
        public async Task NotChangeRequestOrder_WhenOptimizeRouteResultRequestIdsIsNull()
        {
            var optimizeRouteService = new Mock <IOptimizeRouteService>();

            optimizeRouteService.Setup(x => x.OptimizeRoute(It.IsAny <OptimizeRouteCriteria>()))
            .ReturnsAsync(new OptimizeRouteResult())
            .Verifiable();

            var sut = new OptimizeRouteCommandHandler(Context, optimizeRouteService.Object);

            await sut.Handle(new OptimizeRouteCommand { ItineraryId = 1 });

            var requests = Context.ItineraryRequests.Where(x => x.ItineraryId == 1).OrderBy(x => x.OrderIndex).ToList();

            requests[0].Request.Name.ShouldBe("Request 1");
            requests[1].Request.Name.ShouldBe("Request 2");
        }
        public async Task ChangeRequestOrder_WhenOptimizeRouteResultReturnsUpdatedWaypointsOrder()
        {
            var optimizeRouteService = new Mock <IOptimizeRouteService>();

            optimizeRouteService.Setup(x => x.OptimizeRoute(It.IsAny <OptimizeRouteCriteria>()))
            .ReturnsAsync(new OptimizeRouteResult {
                Distance = 10, Duration = 10, RequestIds = new List <Guid> {
                    Request4Id, Request1Id
                }
            });

            var sut = new OptimizeRouteCommandHandler(Context, optimizeRouteService.Object, Mock.Of <IMemoryCache>());

            await sut.Handle(new OptimizeRouteCommand { ItineraryId = 1 });

            var requests = Context.ItineraryRequests.Where(x => x.ItineraryId == 1).OrderBy(x => x.OrderIndex).ToList();

            requests[0].Request.Name.ShouldBe("Request 4");
            requests[1].Request.Name.ShouldBe("Request 1");
        }
        public async Task NotChangeRequestOrder_WhenOptimizeRouteResultDoesNotReturnMatchingRequestIds()
        {
            var optimizeRouteService = new Mock <IOptimizeRouteService>();

            optimizeRouteService.Setup(x => x.OptimizeRoute(It.IsAny <OptimizeRouteCriteria>()))
            .ReturnsAsync(new OptimizeRouteResult {
                Distance = 10, Duration = 10, RequestIds = new List <Guid> {
                    Request4Id, Guid.Empty
                }
            });

            var sut = new OptimizeRouteCommandHandler(Context, optimizeRouteService.Object, Mock.Of <IMemoryCache>());

            await sut.Handle(new OptimizeRouteCommand { ItineraryId = 1 });

            var requests = Context.ItineraryRequests.Where(x => x.ItineraryId == 1).OrderBy(x => x.OrderIndex).ToList();

            requests.First(x => x.RequestId == Request1Id).OrderIndex.ShouldBe(1);
            requests.First(x => x.RequestId == Request4Id).OrderIndex.ShouldBe(2);
        }
        public async Task CallOptimizeRouteService_WhenStartAndEndAddressPresent_WithCorrectCriteria()
        {
            OptimizeRouteCriteria criteria = null;

            var optimizeRouteService = new Mock <IOptimizeRouteService>();

            optimizeRouteService.Setup(x => x.OptimizeRoute(It.IsAny <OptimizeRouteCriteria>()))
            .ReturnsAsync(new OptimizeRouteResult())
            .Callback <OptimizeRouteCriteria>(x => criteria = x)
            .Verifiable();

            var sut = new OptimizeRouteCommandHandler(Context, optimizeRouteService.Object, Mock.Of <IMemoryCache>());

            await sut.Handle(new OptimizeRouteCommand { ItineraryId = 1 });

            optimizeRouteService.Verify(x => x.OptimizeRoute(It.IsAny <OptimizeRouteCriteria>()), Times.Once);
            criteria.StartAddress.ShouldBe(EncodedFullAddress);
            criteria.EndAddress.ShouldBe(EncodedFullAddress);
            criteria.Waypoints.Count.ShouldBe(2);
        }
        public async Task NotChangeRequestOrder_WhenOptimizeRouteResultRequestIdCountDoesNotMatchWaypointCount()
        {
            var optimizeRouteService = new Mock <IOptimizeRouteService>();

            optimizeRouteService.Setup(x => x.OptimizeRoute(It.IsAny <OptimizeRouteCriteria>()))
            .ReturnsAsync(new OptimizeRouteResult {
                Distance = 10, Duration = 10, RequestIds = new List <Guid> {
                    Guid.NewGuid()
                }
            })
            .Verifiable();

            var sut = new OptimizeRouteCommandHandler(Context, optimizeRouteService.Object);

            await sut.Handle(new OptimizeRouteCommand { ItineraryId = 1 });

            var requests = Context.ItineraryRequests.Where(x => x.ItineraryId == 1).OrderBy(x => x.OrderIndex).ToList();

            requests[0].Request.Name.ShouldBe("Request 1");
            requests[1].Request.Name.ShouldBe("Request 2");
        }
        public async Task SetsCorrectCacheEntry_WhenOptimizeRouteResultIsNotSuccess()
        {
            const string statusMsg = "failure";

            var optimizeRouteService = new Mock <IOptimizeRouteService>();

            optimizeRouteService.Setup(x => x.OptimizeRoute(It.IsAny <OptimizeRouteCriteria>()))
            .ReturnsAsync(OptimizeRouteResult.FailedOptimizeRouteResult(statusMsg));

            var cache = new MemoryCache(new MemoryCacheOptions());

            var sut = new OptimizeRouteCommandHandler(Context, optimizeRouteService.Object, cache);

            await sut.Handle(new OptimizeRouteCommand { ItineraryId = 1, UserId = "123" });

            var expectedCacheKey = CacheKeyBuilder.BuildOptimizeRouteCacheKey("123", 1);

            OptimizeRouteResultStatus cachedStatus = null;
            var keyExists = cache.TryGetValue(expectedCacheKey, out cachedStatus);

            keyExists.ShouldBeTrue();
            cachedStatus.IsSuccess.ShouldBeFalse();
            cachedStatus.StatusMessage.ShouldBe(statusMsg);
        }