public async Task And_The_Location_Cookie_Exists_Then_Location_Is_Added_To_Shortlist(
            CreateShortlistItemRequest request,
            ShortlistCookieItem shortlistCookie,
            LocationCookieItem locationCookieItem,
            [Frozen] Mock <ICookieStorageService <ShortlistCookieItem> > mockShortlistCookieService,
            [Frozen] Mock <ICookieStorageService <LocationCookieItem> > mockLocationCookieService,
            [Frozen] Mock <IMediator> mockMediator,
            [Greedy] ShortlistController controller)
        {
            //Arrange
            mockShortlistCookieService
            .Setup(service => service.Get(Constants.ShortlistCookieName))
            .Returns(shortlistCookie);
            mockLocationCookieService.Setup(x => x.Get(Constants.LocationCookieName))
            .Returns(locationCookieItem);
            request.RouteName = string.Empty;

            //Act
            var actual = await controller.CreateShortlistItem(request) as AcceptedResult;

            //Assert
            actual.Should().NotBeNull();
            mockMediator.Verify(x => x.Send(It.Is <CreateShortlistItemForUserCommand>(c =>
                                                                                      c.ShortlistUserId.Equals(shortlistCookie.ShortlistUserId) &&
                                                                                      c.Lat.Equals(locationCookieItem.Lat) &&
                                                                                      c.Lon.Equals(locationCookieItem.Lon) &&
                                                                                      c.LocationDescription.Equals(locationCookieItem.Name) &&
                                                                                      c.Ukprn.Equals(request.Ukprn) &&
                                                                                      c.TrainingCode.Equals(request.TrainingCode)
                                                                                      ), It.IsAny <CancellationToken>()), Times.Once);
        }
        public async Task And_The_Cookie_Does_Not_Exist_Then_A_New_Cookie_Is_Created_And_Used_For_Shortlist(
            CreateShortlistItemRequest request,
            [Frozen] Mock <ICookieStorageService <ShortlistCookieItem> > mockShortlistCookieService,
            [Frozen] Mock <ICookieStorageService <LocationCookieItem> > mockLocationCookieService,
            [Frozen] Mock <IMediator> mockMediator,
            [Greedy] ShortlistController controller)
        {
            //Arrange
            mockShortlistCookieService
            .Setup(service => service.Get(Constants.ShortlistCookieName))
            .Returns((ShortlistCookieItem)null);
            mockLocationCookieService.Setup(x => x.Get(Constants.LocationCookieName))
            .Returns((LocationCookieItem)null);
            request.RouteName = string.Empty;

            //Act
            var actual = await controller.CreateShortlistItem(request) as AcceptedResult;

            //Assert
            actual.Should().NotBeNull();
            mockMediator.Verify(x => x.Send(It.Is <CreateShortlistItemForUserCommand>(c =>
                                                                                      c.Lat == null &&
                                                                                      c.Lon == null &&
                                                                                      c.LocationDescription == null &&
                                                                                      c.Ukprn.Equals(request.Ukprn) &&
                                                                                      c.TrainingCode.Equals(request.TrainingCode)
                                                                                      ), It.IsAny <CancellationToken>()), Times.Once);
            mockShortlistCookieService.Verify(x =>
                                              x.Update(
                                                  Constants.ShortlistCookieName,
                                                  It.Is <ShortlistCookieItem>(c => c.ShortlistUserId != Guid.Empty),
                                                  30), Times.Once);
        }
        public async Task And_Cookie_Exists_Then_Adds_To_Shortlist_For_User(
            Guid expectedId,
            CreateShortlistItemRequest request,
            ShortlistCookieItem shortlistCookie,
            [Frozen] Mock <ICookieStorageService <ShortlistCookieItem> > mockShortlistCookieService,
            [Frozen] Mock <ICookieStorageService <LocationCookieItem> > mockLocationCookieService,
            [Frozen] Mock <IMediator> mockMediator,
            [Greedy] ShortlistController controller)
        {
            //Arrange
            mockMediator.Setup(x => x.Send(It.Is <CreateShortlistItemForUserCommand>(c =>
                                                                                     c.ShortlistUserId.Equals(shortlistCookie.ShortlistUserId) &&
                                                                                     c.Lat == null &&
                                                                                     c.Lon == null &&
                                                                                     c.LocationDescription == null &&
                                                                                     c.Ukprn.Equals(request.Ukprn) &&
                                                                                     c.TrainingCode.Equals(request.TrainingCode)
                                                                                     ), It.IsAny <CancellationToken>())).ReturnsAsync(expectedId);
            mockShortlistCookieService
            .Setup(service => service.Get(Constants.ShortlistCookieName))
            .Returns(shortlistCookie);
            mockLocationCookieService.Setup(x => x.Get(Constants.LocationCookieName))
            .Returns((LocationCookieItem)null);
            request.RouteName = string.Empty;

            //Act
            var actual = await controller.CreateShortlistItem(request) as AcceptedResult;

            //Assert
            actual.Should().NotBeNull();
            Guid.Parse(actual.Value.ToString()).Should().Be(expectedId);
            mockShortlistCookieService.Verify(x => x.Update(Constants.ShortlistCookieName, shortlistCookie, 30), Times.Once);
        }
        public async Task And_If_ProviderName_Is_In_The_Request_Is_Encoded_Using_The_Protector(
            CreateShortlistItemRequest request,
            ShortlistCookieItem shortlistCookie,
            LocationCookieItem locationCookieItem,
            [Frozen] Mock <ICookieStorageService <ShortlistCookieItem> > mockShortlistCookieService,
            [Frozen] Mock <ICookieStorageService <LocationCookieItem> > mockLocationCookieService,
            [Frozen] Mock <IDataProtector> protector,
            [Frozen] Mock <IDataProtectionProvider> provider,
            [Greedy] ShortlistController controller)
        {
            //Arrange
            mockShortlistCookieService
            .Setup(service => service.Get(Constants.ShortlistCookieName))
            .Returns(shortlistCookie);
            mockLocationCookieService.Setup(x => x.Get(Constants.LocationCookieName))
            .Returns(locationCookieItem);
            request.RouteName = RouteNames.CourseProviders;

            //Act
            await controller.CreateShortlistItem(request);

            //Assert
            protector.Verify(c => c.Protect(It.Is <byte[]>(
                                                x => x[0].Equals(Encoding.UTF8.GetBytes($"{request.ProviderName}")[0]))), Times.Once);
        }
        public async Task And_If_There_Is_A_Route_Name_Then_It_Is_Redirected(CreateShortlistItemRequest request,
                                                                             ShortlistCookieItem shortlistCookie,
                                                                             LocationCookieItem locationCookieItem,
                                                                             [Frozen] Mock <ICookieStorageService <ShortlistCookieItem> > mockShortlistCookieService,
                                                                             [Frozen] Mock <ICookieStorageService <LocationCookieItem> > mockLocationCookieService,
                                                                             [Frozen] Mock <IMediator> mockMediator,
                                                                             [Greedy] ShortlistController controller)
        {
            //Arrange
            mockShortlistCookieService
            .Setup(service => service.Get(Constants.ShortlistCookieName))
            .Returns(shortlistCookie);
            mockLocationCookieService.Setup(x => x.Get(Constants.LocationCookieName))
            .Returns(locationCookieItem);
            request.RouteName = RouteNames.CourseProviders;

            //Act
            var actual = await controller.CreateShortlistItem(request) as RedirectToRouteResult;

            //Assert
            actual.Should().NotBeNull();
            actual.RouteName.Should().Be(request.RouteName);
            actual.RouteValues.Should().ContainKey("id");
            actual.RouteValues["id"].Should().Be(request.TrainingCode);
            actual.RouteValues.Should().ContainKey("providerId");
            actual.RouteValues["providerId"].Should().Be(request.Ukprn);
        }
        public async Task <IActionResult> CreateShortlistItem(CreateShortlistItemRequest request)
        {
            var cookie = _shortlistCookieService.Get(Constants.ShortlistCookieName);

            if (cookie == null)
            {
                cookie = new ShortlistCookieItem
                {
                    ShortlistUserId = Guid.NewGuid()
                };
            }
            _shortlistCookieService.Update(Constants.ShortlistCookieName, cookie, 30);

            var location = _locationCookieService.Get(Constants.LocationCookieName);

            var result = await _mediator.Send(new CreateShortlistItemForUserCommand
            {
                Lat   = location?.Lat,
                Lon   = location?.Lon,
                Ukprn = request.Ukprn,
                LocationDescription = string.IsNullOrEmpty(location?.Name) ? null : location.Name,
                TrainingCode        = request.TrainingCode,
                ShortlistUserId     = cookie.ShortlistUserId
            });

            if (!string.IsNullOrEmpty(request.RouteName))
            {
                return(RedirectToRoute(request.RouteName, new
                {
                    Id = request.TrainingCode,
                    ProviderId = request.Ukprn,
                    Added = string.IsNullOrEmpty(request.ProviderName) ? "" : WebEncoders.Base64UrlEncode(_protector.Protect(
                                                                                                              System.Text.Encoding.UTF8.GetBytes($"{request.ProviderName}")))
                }));
            }

            return(Accepted(result));
        }