public async Task IsHealthOk_ReturnsAsExpected(bool blobOk, string blobMessage)
        {
            //Arrange
            IBlobClient blobClient = Substitute.For <IBlobClient>();

            blobClient
            .IsHealthOk()
            .Returns((blobOk, blobMessage));

            ProviderFundingVersionService providerFundingVersionService = CreateProviderFundingVersionService(blobClient: blobClient);

            ServiceHealth health = await providerFundingVersionService.IsHealthOk();

            health.Name
            .Should()
            .Be(nameof(ProviderFundingVersionService));

            health.Dependencies.Count.Should().Be(1);

            health
            .Dependencies
            .Count(x => x.HealthOk == blobOk && x.Message == blobMessage)
            .Should()
            .Be(1);
        }
        public async Task GetFundings_GivenPublishedProviderVersionIncludedInFunding_ReturnsFundingIds()
        {
            //Arrange
            IEnumerable <dynamic> fundingIds = new[] { new { fundingId = "id1" } };

            IPublishedFundingRepository publishedFundingRepository = Substitute.For <IPublishedFundingRepository>();

            ProviderFundingVersionService service = CreateProviderFundingVersionService(publishedFundingRepository: publishedFundingRepository);

            publishedFundingRepository.GetFundings(Arg.Is <string>(publishedProviderVersion))
            .Returns(fundingIds);

            //Act
            IActionResult result = await service.GetFundings(publishedProviderVersion);

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

            OkObjectResult contentResult = result as OkObjectResult;

            IEnumerable <dynamic> fundingIdResults = contentResult.Value as IEnumerable <dynamic>;

            fundingIdResults.Should()
            .BeEquivalentTo(fundingIds);
        }
        public async Task GetProviderFundingVersionsBody_GivenGetBlobReferenceCausesException_LogsAndReturnsInternalServerError()
        {
            //Arrange
            ILogger     logger     = CreateLogger();
            IBlobClient blobClient = CreateBlobClient();

            blobClient
            .BlobExistsAsync(blobName)
            .Returns(true);

            blobClient
            .GetBlobReferenceFromServerAsync(blobName)
            .Throws(new Exception());

            string errorMessage = $"Failed to fetch blob '{blobName}' from azure storage";

            ProviderFundingVersionService service = CreateProviderFundingVersionService(logger, blobClient);

            //Act
            IActionResult result = await service.GetProviderFundingVersion(providerFundingVersion);

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

            logger
            .Received(1)
            .Error(Arg.Any <Exception>(), Arg.Is(errorMessage));
        }
        public async Task GetProviderFundingVersionsBody_GivenNullOrEmptyId_ReturnsBadRequest()
        {
            //Arrange
            string id = "";

            ProviderFundingVersionService service = CreateProviderFundingVersionService();

            //Act
            IActionResult result = await service.GetProviderFundingVersion(id);

            //Assert
            result
            .Should()
            .BeAssignableTo <BadRequestObjectResult>()
            .Which
            .Value
            .Should()
            .Be("Null or empty id provided.");
        }
        public async Task GetProviderFundingVersionsBody_GivenBlobDoesNotExists_ReturnsNotFound()
        {
            //Arrange
            ILogger     logger     = CreateLogger();
            IBlobClient blobClient = CreateBlobClient();

            ProviderFundingVersionService service = CreateProviderFundingVersionService(logger, blobClient);

            //Act
            IActionResult result = await service.GetProviderFundingVersion(providerFundingVersion);

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

            logger
            .Received(1)
            .Error(Arg.Is($"Blob '{blobName}' does not exist."));
        }
        public async Task GetProviderFundingVersionsBody_GivenReturnsFromBlobStorage_ReturnsOK(bool isFileSystemCacheEnabled,
                                                                                               int expectedCacheAddCount)
        {
            //Arrange
            string template = "just a string";

            byte[] bytes = Encoding.UTF8.GetBytes(template);

            Stream memoryStream = new MemoryStream(bytes);

            ILogger          logger          = CreateLogger();
            ICloudBlob       cloudBlob       = CreateBlob();
            IFileSystemCache fileSystemCache = CreateFileSystemCache();
            IExternalApiFileSystemCacheSettings cacheSettings = Substitute.For <IExternalApiFileSystemCacheSettings>();

            cacheSettings.IsEnabled.Returns(isFileSystemCacheEnabled);

            IBlobClient blobClient = CreateBlobClient();

            blobClient
            .BlobExistsAsync(blobName)
            .Returns(true);

            blobClient
            .GetBlobReferenceFromServerAsync(blobName)
            .Returns(cloudBlob);

            blobClient
            .DownloadToStreamAsync(cloudBlob)
            .Returns(memoryStream);

            ProviderFundingVersionService service = CreateProviderFundingVersionService(logger, blobClient, fileSystemCache, cacheSettings);

            //Act
            IActionResult result = await service.GetProviderFundingVersion(providerFundingVersion);

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

            ContentResult contentResult = result as ContentResult;

            contentResult
            .ContentType
            .Should()
            .Be("application/json");

            contentResult
            .StatusCode
            .Should()
            .Be((int)HttpStatusCode.OK);

            contentResult
            .Content
            .Should()
            .Be(template);

            fileSystemCache
            .Received(expectedCacheAddCount)
            .Add(Arg.Is <ProviderFundingFileSystemCacheKey>(_ => _.Key == providerFundingVersion),
                 memoryStream,
                 CancellationToken.None);
        }
        public async Task GetProviderFundingVersionsBody_GivenReturnsFromFileSystemCacheAndSkipBlobClientFetch_ReturnsOK()
        {
            //Arrange
            string template = "just a string";

            byte[] bytes = Encoding.UTF8.GetBytes(template);

            Stream memoryStream = new MemoryStream(bytes);

            ILogger          logger          = CreateLogger();
            IFileSystemCache fileSystemCache = CreateFileSystemCache();
            IBlobClient      blobClient      = CreateBlobClient();

            fileSystemCache.Exists(Arg.Is <ProviderFundingFileSystemCacheKey>(
                                       _ => _.Key == providerFundingVersion))
            .Returns(true);

            fileSystemCache.Get(Arg.Is <ProviderFundingFileSystemCacheKey>(
                                    _ => _.Key == providerFundingVersion))
            .Returns(memoryStream);

            ProviderFundingVersionService service = CreateProviderFundingVersionService(logger, blobClient, fileSystemCache);

            //Act
            IActionResult result = await service.GetProviderFundingVersion(providerFundingVersion);

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

            ContentResult contentResult = result as ContentResult;

            contentResult
            .ContentType
            .Should()
            .Be("application/json");

            contentResult
            .StatusCode
            .Should()
            .Be((int)HttpStatusCode.OK);

            contentResult
            .Content
            .Should()
            .Be(template);

            await blobClient
            .Received(0)
            .BlobExistsAsync(providerFundingVersion);

            await blobClient
            .Received(0)
            .GetAsync(Arg.Any <string>());

            fileSystemCache
            .Received(0)
            .Add(Arg.Is <ProviderFundingFileSystemCacheKey>(_ => _.Key == providerFundingVersion),
                 memoryStream,
                 CancellationToken.None);
        }