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

            HttpStatusCode statusCode = HttpStatusCode.OK;

            IPolicyRepository policyRepository = CreatePolicyRepository();

            policyRepository
            .SaveFundingDate(
                Arg.Is <FundingDate>(_ => _
                                     .FundingStreamId == _fundingStreamId))
            .Returns(statusCode);

            FundingDateService fundingDateService = CreateFundingDateService(logger: logger, policyRepository: policyRepository);

            FundingDateViewModel fundingDateViewModel = CreateFundingDateViewModel();

            // Act
            IActionResult result = await fundingDateService.SaveFundingDate(
                null, null, _fundingStreamId, _fundingPeriodId, _fundingLineId, fundingDateViewModel);

            // Assert
            result
            .Should()
            .BeOfType <CreatedAtActionResult>()
            .Which
            .Should()
            .NotBeNull();

            logger
            .Received(1)
            .Information(Arg.Is($"Successfully saved funding date for funding stream id: {_fundingStreamId} and period id: {_fundingPeriodId} and funding line id: {_fundingLineId} to cosmos db"));
        }
        public async Task SaveFundingDate_GivenInvalidSaveFundingDateResult_ReturnsSaveFundingDateResult()
        {
            // Arrange
            ILogger logger = CreateLogger();

            HttpStatusCode statusCode = HttpStatusCode.InternalServerError;

            IPolicyRepository policyRepository = CreatePolicyRepository();

            policyRepository
            .SaveFundingDate(
                Arg.Is <FundingDate>(_ => _
                                     .FundingStreamId == _fundingStreamId))
            .Returns(statusCode);

            FundingDateService fundingDateService = CreateFundingDateService(logger: logger, policyRepository: policyRepository);

            FundingDateViewModel fundingDateViewModel = CreateFundingDateViewModel();

            // Act
            IActionResult result = await fundingDateService.SaveFundingDate(
                null, null, _fundingStreamId, _fundingPeriodId, _fundingLineId, fundingDateViewModel);

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

            logger
            .Received(1)
            .Error(Arg.Is($"Failed to save funding date for funding stream id: {_fundingStreamId} and period id: {_fundingPeriodId} and funding line id: {_fundingLineId} to cosmos db with status {(int)statusCode}"));
        }
        public async Task SaveFundingDate_GivenInvalidViewModel_ReturnsBadRequestResult()
        {
            // Arrange
            ILogger logger = CreateLogger();

            ValidationResult validationResult = new ValidationResult(
                new List <ValidationFailure>
            {
                new ValidationFailure("FundingStreamId", "error")
            });
            IValidator <FundingDate> validator = CreateValidator(validationResult);

            FundingDateService fundingDateService = CreateFundingDateService(logger: logger, validator: validator);

            FundingDateViewModel fundingDateViewModel = CreateFundingDateViewModel();

            // Act
            IActionResult result = await fundingDateService.SaveFundingDate(
                null, null, _fundingStreamId, _fundingPeriodId, _fundingLineId, fundingDateViewModel);

            // Assert
            result
            .Should()
            .BeOfType <BadRequestObjectResult>();
        }
        public async Task GetFundingDate_GivenFundingDateNotFound_ReturnsNotFoundResult()
        {
            // Arrange
            ILogger logger = CreateLogger();

            FundingDateService fundingDateService = CreateFundingDateService(logger: logger);

            // Act
            IActionResult result = await fundingDateService.GetFundingDate(_fundingStreamId, _fundingPeriodId, _fundingLineId);

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

            logger
            .Received(1)
            .Error(Arg.Is($"No funding Dates were found for funding stream id : {_fundingStreamId}"));
        }
        public async Task GetFundingDate_GivenEmptyFundingLineId_ReturnsBadRequestResult()
        {
            // Arrange
            ILogger logger = CreateLogger();

            FundingDateService fundingDateService = CreateFundingDateService(logger: logger);

            // Act
            IActionResult result = await fundingDateService.GetFundingDate(_fundingStreamId, _fundingPeriodId, null);

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

            logger
            .Received(1)
            .Error(Arg.Is("No funding line Id was provided to GetFundingDate"));
        }
        public async Task GetFundingDate_GivenFundingDate_ReturnsOkResult()
        {
            // Arrange
            ILogger logger = CreateLogger();

            string fundingDateId = $"fundingdate-{_fundingStreamId}-{_fundingPeriodId}-{_fundingLineId}";

            IPolicyRepository policyRepository = CreatePolicyRepository();

            policyRepository
            .GetFundingDate(fundingDateId)
            .Returns(NewFundingDate(_ => _.WithFundingStreamId(_fundingStreamId)));

            FundingDateService fundingDateService = CreateFundingDateService(logger: logger, policyRepository: policyRepository);

            // Act
            IActionResult result = await fundingDateService.GetFundingDate(_fundingStreamId, _fundingPeriodId, _fundingLineId);

            // Assert
            result
            .Should()
            .BeOfType <OkObjectResult>()
            .Which
            .Value
            .Should()
            .BeOfType <FundingDate>()
            .And
            .Should()
            .NotBeNull();

            FundingDate fundingDate = (result as OkObjectResult).Value as FundingDate;

            fundingDate
            .FundingStreamId
            .Should()
            .Be(_fundingStreamId);
        }