public async Task GetFundingPeriods_GivenNullOrEmptyPeriodsReturned_LogsAndReturnsOKWithEmptyList()
        {
            // Arrange
            ILogger logger = CreateLogger();

            IEnumerable <FundingPeriod> Periods = null;

            IPolicyRepository policyRepository = CreatePolicyRepository();

            policyRepository
            .GetFundingPeriods()
            .Returns(Periods);

            FundingPeriodService fundingPeriodService = CreateFundingPeriodService(logger: logger, policyRepository: policyRepository);

            // Act
            IActionResult result = await fundingPeriodService.GetFundingPeriods();

            // Assert
            result
            .Should()
            .BeOfType <OkObjectResult>();

            OkObjectResult objectResult = result as OkObjectResult;

            IEnumerable <FundingPeriod> values = objectResult.Value as IEnumerable <FundingPeriod>;

            values
            .Should()
            .NotBeNull();

            logger
            .Received(1)
            .Error(Arg.Is("No funding periods were returned"));
        }
        public async Task GetAllFundingPeriods_GivenNullOrEmptyPeriodsReturned_LogsAndReturnsOKWithEmptyList()
        {
            // Arrange
            ILogger logger = CreateLogger();

            IEnumerable <FundingPeriod> Periods = null;

            IPolicyRepository policyRepository = CreatePolicyRepository();

            policyRepository
            .GetFundingPeriods()
            .Returns(Periods);

            FundingPeriodService fundingPeriodService = CreateFundingPeriodService(logger: logger, policyRepository: policyRepository);

            // Act
            IEnumerable <FundingPeriod> result = await fundingPeriodService.GetAllFundingPeriods();

            // Assert
            result
            .Should()
            .BeOfType <FundingPeriod[]>()
            .Which
            .Should()
            .AllBeEquivalentTo(Periods);

            logger
            .Received(1)
            .Error(Arg.Is("No funding periods were returned"));
        }
        public async Task SaveFundingPeriod_GivenValidJsonButFailedToSaveToDatabase_ReturnsStatusCode()
        {
            //Arrange
            ILogger logger = CreateLogger();

            IPolicyRepository policyRepository = CreatePolicyRepository();

            policyRepository
            .When(x => x.SaveFundingPeriods(Arg.Any <FundingPeriod[]>()))
            .Do(x => { throw new Exception(); });

            FundingPeriodService fundingPeriodService = CreateFundingPeriodService(logger: logger, policyRepository: policyRepository);

            string errorMessage = $"Exception occurred writing json file to cosmos db";

            //Act
            IActionResult result = await fundingPeriodService.SaveFundingPeriods(CreateFundingPeriodsJsonModel());

            //Assert
            result
            .Should()
            .BeOfType <InternalServerErrorResult>()
            .Which
            .Value
            .Should()
            .Be(errorMessage);

            logger
            .Received(1)
            .Error(Arg.Any <Exception>(), Arg.Is(errorMessage));
        }
        public async Task SaveFundingStream_GivenValidYamlAndSaveWasSuccesful_ReturnsOK()
        {
            //Arrange
            ILogger logger = CreateLogger();

            IPolicyRepository policyRepository = CreatePolicyRepository();

            ICacheProvider cacheProvider = CreateCacheProvider();

            FundingPeriodService fundingPeriodService = CreateFundingPeriodService(logger: logger, policyRepository: policyRepository, cacheProvider: cacheProvider);

            //Act
            IActionResult result = await fundingPeriodService.SaveFundingPeriods(CreateFundingPeriodsJsonModel());

            //Assert
            result
            .Should()
            .BeOfType <OkResult>();

            logger
            .Received(1)
            .Information(Arg.Is($"Successfully saved file to cosmos db"));

            await
            policyRepository
            .Received(1)
            .SaveFundingPeriods(Arg.Is <FundingPeriod[]>(m => m.Count() == 4));

            await cacheProvider
            .Received(1)
            .RemoveAsync <FundingPeriod[]>(CacheKeys.FundingPeriods);
        }
        public async Task GetFundingPeriodById__GivenFundingStreamnWasFound_ReturnsSuccess()
        {
            // Arrange
            const string fundingPeriodId = "fp-1";

            FundingPeriod fundingPeriod = new FundingPeriod
            {
                Id = fundingPeriodId
            };

            IPolicyRepository policyRepository = CreatePolicyRepository();

            policyRepository
            .GetFundingPeriodById(Arg.Is(fundingPeriodId))
            .Returns(fundingPeriod);

            FundingPeriodService fundingPeriodService = CreateFundingPeriodService(policyRepository: policyRepository);

            // Act
            IActionResult result = await fundingPeriodService.GetFundingPeriodById(fundingPeriodId);

            // Assert
            result
            .Should()
            .BeOfType <OkObjectResult>()
            .Which
            .Value
            .Should()
            .Be(fundingPeriod);
        }
        public async Task GetFundingPeriodById_GivenFundingPeriodWasNotFound_ReturnsNotFound()
        {
            // Arrange
            const string fundingPeriodId = "fp-1";

            ILogger logger = CreateLogger();

            IPolicyRepository policyRepository = CreatePolicyRepository();

            policyRepository
            .GetFundingPeriodById(Arg.Is(fundingPeriodId))
            .Returns((FundingPeriod)null);

            FundingPeriodService fundingPeriodService = CreateFundingPeriodService(logger: logger, policyRepository: policyRepository);

            // Act
            IActionResult result = await fundingPeriodService.GetFundingPeriodById(fundingPeriodId);

            // Assert
            result
            .Should()
            .BeOfType <NotFoundResult>();

            logger
            .Received(1)
            .Error(Arg.Is($"No funding period was returned for funding period id: '{fundingPeriodId}'"));
        }
        public async Task SaveFundingPeriod_GivenNoJsonWasProvided_ReturnsBadRequest()
        {
            //Arrange
            ILogger logger = CreateLogger();

            FundingPeriodService fundingPeriodService = CreateFundingPeriodService(logger: logger);

            //Act
            IActionResult result = await fundingPeriodService.SaveFundingPeriods(null);

            //Assert
            result
            .Should()
            .BeOfType <BadRequestObjectResult>();

            logger
            .Received(1)
            .Error(Arg.Is($"Null or empty json provided for file"));
        }
        public async Task GetFundingPeriods_GivenPeriodsAlreadyInCache_ReturnsOKWithResultsFromCache()
        {
            // Arrange
            ILogger logger = CreateLogger();

            IEnumerable <FundingPeriod> Periods = new[]
            {
                new FundingPeriod(),
                new FundingPeriod()
            };

            ICacheProvider cacheProvider = CreateCacheProvider();

            cacheProvider
            .GetAsync <FundingPeriod[]>(Arg.Is(CacheKeys.FundingPeriods))
            .Returns(Periods.ToArray());

            IPolicyRepository policyRepository = CreatePolicyRepository();

            FundingPeriodService PeriodsService = CreateFundingPeriodService(logger, cacheProvider, policyRepository);

            // Act
            IActionResult result = await PeriodsService.GetFundingPeriods();

            // Assert
            result
            .Should()
            .BeOfType <OkObjectResult>();

            OkObjectResult objectResult = result as OkObjectResult;

            IEnumerable <FundingPeriod> values = objectResult.Value as IEnumerable <FundingPeriod>;

            values
            .Should()
            .HaveCount(2);

            await
            policyRepository
            .DidNotReceive()
            .GetFundingPeriods();
        }
        public async Task GetFundingPeriods_GivenPeriodsReturned_ReturnsOKWithResults()
        {
            // Arrange
            ILogger logger = CreateLogger();

            IEnumerable <FundingPeriod> Periods = new[]
            {
                new FundingPeriod(),
                new FundingPeriod()
            };

            IPolicyRepository policyRepository = CreatePolicyRepository();

            policyRepository
            .GetFundingPeriods()
            .Returns(Periods);

            ICacheProvider cacheProvider = CreateCacheProvider();

            FundingPeriodService fundingPeriodService = CreateFundingPeriodService(logger, cacheProvider, policyRepository);

            // Act
            IActionResult result = await fundingPeriodService.GetFundingPeriods();

            // Assert
            result
            .Should()
            .BeOfType <OkObjectResult>();

            OkObjectResult objectResult = result as OkObjectResult;

            IEnumerable <FundingPeriod> values = objectResult.Value as IEnumerable <FundingPeriod>;

            values
            .Should()
            .HaveCount(2);

            await
            cacheProvider
            .Received(1)
            .SetAsync <FundingPeriod[]>(Arg.Is(CacheKeys.FundingPeriods), Arg.Is <FundingPeriod[]>(m => m.SequenceEqual(Periods)));
        }
        public async Task GetFundingPeriodById_GivenFundingStreamIdDoesNotExist_ReturnsBadRequest(string fundingStreamId)
        {
            // Arrange
            ILogger logger = CreateLogger();

            FundingPeriodService fundingPeriodService = CreateFundingPeriodService(logger: logger);

            // Act
            IActionResult result = await fundingPeriodService.GetFundingPeriodById(fundingStreamId);

            // Assert
            result
            .Should()
            .BeOfType <BadRequestObjectResult>()
            .Which
            .Value
            .Should()
            .Be("Null or empty funding period id provided");

            logger
            .Received(1)
            .Error(Arg.Is("No funding period id was provided to GetFundingPeriodById"));
        }
        public async Task GetAllFundingPeriods_ReturnsSuccess()
        {
            ILogger logger = CreateLogger();

            IEnumerable <FundingPeriod> Periods = new List <FundingPeriod>
            {
                new FundingPeriod(),
                new FundingPeriod()
            };

            IPolicyRepository policyRepository = CreatePolicyRepository();

            policyRepository
            .GetFundingPeriods()
            .Returns(Periods);

            FundingPeriodService fundingPeriodService = CreateFundingPeriodService(logger: logger, policyRepository: policyRepository);

            IEnumerable <FundingPeriod> result = await fundingPeriodService.GetAllFundingPeriods();

            result
            .Should()
            .HaveCount(2);
        }