Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
95f27aa
feat: 7723-update-blobstoragehelper-tests
Swapnil261188 Mar 5, 2025
083555f
feat: 7723-merging with main
Swapnil261188 Mar 5, 2025
4e63c62
feat: 7723-review comment incorporation
Swapnil261188 Mar 6, 2025
6e34fe2
feat: 7723-review comment updates and adding skipapicheck logic in ya…
Swapnil261188 Mar 6, 2025
55348f1
Feat: 7723-test commit
Swapnil261188 Mar 6, 2025
e65bfda
feat: 7723-restoring previous version
Swapnil261188 Mar 6, 2025
e5a3321
feat: 7723-adding setup
Swapnil261188 Mar 6, 2025
1fe1010
feat: 7723-updating tests
Swapnil261188 Mar 6, 2025
f0fb73c
feat: 7723-testing errors file
Swapnil261188 Mar 10, 2025
3cd6e7c
feat: 7723-testing fix
Swapnil261188 Mar 10, 2025
915190f
feat: 7723-testing fix 2
Swapnil261188 Mar 10, 2025
e90d9eb
feat: 7723-testing fix 3
Swapnil261188 Mar 10, 2025
c1512f7
feat: 7723-testing fix 4
Swapnil261188 Mar 10, 2025
504cdd9
feat: 7723-testing fix 5
Swapnil261188 Mar 10, 2025
4e54045
feat: 7723-testing fix 6
Swapnil261188 Mar 10, 2025
cc6f64f
feat: 7723-testing fix 7
Swapnil261188 Mar 10, 2025
eece008
feat: 7723-testing fix 8
Swapnil261188 Mar 10, 2025
c9d2e80
feat: 7723-testing fix 9
Swapnil261188 Mar 11, 2025
4cd2bad
feat: 7723-testing fix 10
Swapnil261188 Mar 11, 2025
6bc145e
feat: 7723-testing fix 11
Swapnil261188 Mar 11, 2025
b84d755
feat: 7723-testing fix 12
Swapnil261188 Mar 11, 2025
2581d7a
feat: 7723-testing fix 13
Swapnil261188 Mar 11, 2025
ecb5aa0
feat: 7723-testing fix 14
Swapnil261188 Mar 11, 2025
e30c004
feat: 7723-testing fix 15
Swapnil261188 Mar 11, 2025
355c5bd
feat: 7723-testing fix 16
Swapnil261188 Mar 11, 2025
0b52044
feat: 7723-testing fix 17
Swapnil261188 Mar 11, 2025
d231a00
feat: 7723-testing fix 18
Swapnil261188 Mar 11, 2025
91a771a
feat: 7723-testing fix 19
Swapnil261188 Mar 11, 2025
e2e3010
feat: 7723-testing fix 20
Swapnil261188 Mar 11, 2025
986ad68
feat: 7723-testing fix 21
Swapnil261188 Mar 11, 2025
ea9f7e4
feat: 7723-testing fix 22
Swapnil261188 Mar 11, 2025
93b863f
feat: 7723-testing fix 23
Swapnil261188 Mar 11, 2025
26cea6f
feat: 7723-testing fix 24
Swapnil261188 Mar 11, 2025
b004678
feat: 7723-testing fix 25
Swapnil261188 Mar 11, 2025
4d42f13
feat: 7723-final testing fix
Swapnil261188 Mar 11, 2025
bc329e4
feat: 7723-merging with main
Swapnil261188 Mar 11, 2025
c59f500
feat: 7723-final changes
Swapnil261188 Mar 11, 2025
1456c5e
Merge branch 'main' into DTOSS-7723-Update-BlobStorageHelper-tests
andrewmorris43 Mar 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/stage-2-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ jobs:
with:
comment-title: 'Unit Test Results'
results-path: ./tests/UnitTests/results-unit/*.trx

test-lint:
name: "Linting"
runs-on: ubuntu-latest
Expand Down Expand Up @@ -77,6 +78,7 @@ jobs:
- name: "Save the coverage check result"
run: |
echo "Nothing to save"

perform-static-analysis:
name: "Perform static analysis"
needs: [test-unit]
Expand Down
2 changes: 1 addition & 1 deletion application/CohortManager/compose.deps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@ services:
condition: service_healthy
environment:
- PASSWORD=${PASSWORD}
- DB_NAME=${DB_NAME}
- DB_NAME=${DB_NAME}
6 changes: 6 additions & 0 deletions application/CohortManager/src/Functions/Functions.sln
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReadRulesTests", "..\..\..\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HttpParserTests", "..\..\..\..\tests\UnitTests\SharedTests\HttpParserTests\HttpParserTests.csproj", "{C86FDA63-AA51-4B5F-A69B-DEF0266E268F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlobStorageHelperTests", "..\..\..\..\tests\UnitTests\SharedTests\BlobStorageHelperTests\BlobStorageHelperTests.csproj", "{7A074C8A-CC8B-4403-89CE-6B20BCD23342}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -590,6 +592,10 @@ Global
{1FCC5D88-C291-46E0-84BE-A8FD465FD509}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1FCC5D88-C291-46E0-84BE-A8FD465FD509}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1FCC5D88-C291-46E0-84BE-A8FD465FD509}.Release|Any CPU.Build.0 = Release|Any CPU
{7A074C8A-CC8B-4403-89CE-6B20BCD23342}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7A074C8A-CC8B-4403-89CE-6B20BCD23342}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7A074C8A-CC8B-4403-89CE-6B20BCD23342}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7A074C8A-CC8B-4403-89CE-6B20BCD23342}.Release|Any CPU.Build.0 = Release|Any CPU
{115F417D-C015-4ABE-9438-09CE31114CEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{115F417D-C015-4ABE-9438-09CE31114CEE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{115F417D-C015-4ABE-9438-09CE31114CEE}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
namespace NHS.CohortManager.Tests.UnitTests.SharedTests;


using System;
using Common;
using System.IO;
using Model;
using System.Threading.Tasks;
using Azure;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using Azure.Storage.Blobs.Specialized;
using Microsoft.Extensions.Logging;
using Moq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Diagnostics;
using System.Text;


[TestClass]
public class BlobStorageHelperTests
{
private Mock<BlobServiceClient> _mockBlobServiceClient;
private Mock<BlobContainerClient> _mockBlobContainerClient;
private Mock<BlobClient> _mockBlobClient;
private Mock<ILogger<BlobStorageHelper>> _mockLogger;
private BlobStorageHelper _blobStorageHelper;

private readonly string _connectionString = "UseDevelopmentStorage=true"; // Azurite Connection String
private readonly string _containerName = "test-container";
private readonly string _fileName = "testfile.txt";

[TestInitialize]


public void Setup()
{
_mockBlobServiceClient = new Mock<BlobServiceClient>();
_mockBlobContainerClient = new Mock<BlobContainerClient>();
_mockBlobClient = new Mock<BlobClient>();
_mockLogger = new Mock<ILogger<BlobStorageHelper>>();

_mockBlobServiceClient
.Setup(m => m.GetBlobContainerClient(It.IsAny<string>()))
.Returns(_mockBlobContainerClient.Object);

_mockBlobContainerClient
.Setup(m => m.GetBlobClient(It.IsAny<string>()))
.Returns(_mockBlobClient.Object);

_blobStorageHelper = new BlobStorageHelper(_mockLogger.Object);
}

public interface IBlobStorageHelperWrapper
{
Task<BlobFile> GetFileFromBlobStorage(string connectionString, string containerName, string fileName);
Task<bool> CopyFileAsync(string connectionString, string fileName, string containerName);
}
public interface IBlobCopyService
{
Task<bool> CopyFileAsync(string connectionString, string fileName, string containerName);
}


public class BlobCopyService : IBlobCopyService
{
private readonly ILogger<BlobCopyService> _logger;

public BlobCopyService(ILogger<BlobCopyService> logger)
{
_logger = logger;
}

public async Task<bool> CopyFileAsync(string connectionString, string fileName, string containerName)
{
try
{
var sourceBlobServiceClient = new BlobServiceClient(connectionString);
var sourceContainerClient = sourceBlobServiceClient.GetBlobContainerClient(containerName);
var sourceBlobClient = sourceContainerClient.GetBlobClient(fileName);

var sourceBlobLease = new BlobLeaseClient(sourceBlobClient);

var destinationBlobServiceClient = new BlobServiceClient(connectionString);
var destinationContainerClient = destinationBlobServiceClient.GetBlobContainerClient(Environment.GetEnvironmentVariable("fileExceptions"));
var destinationBlobClient = destinationContainerClient.GetBlobClient(fileName);

await destinationContainerClient.CreateIfNotExistsAsync(PublicAccessType.None);

await sourceBlobLease.AcquireAsync(BlobLeaseClient.InfiniteLeaseDuration);

var copyOperation = await destinationBlobClient.StartCopyFromUriAsync(sourceBlobClient.Uri);
await copyOperation.WaitForCompletionAsync();

await sourceBlobLease.ReleaseAsync();

return true;
}
catch (RequestFailedException ex)
{
_logger.LogError(ex, "There has been a problem while copying the file: {Message}", ex.Message);
return false;
}
}
}
public class BlobStorageHelperWrapper : IBlobStorageHelperWrapper
{
private readonly BlobStorageHelper _blobStorageHelper;
private readonly IBlobCopyService _blobCopyService;

public BlobStorageHelperWrapper(BlobStorageHelper blobStorageHelper, IBlobCopyService blobCopyService)
{
_blobStorageHelper = blobStorageHelper;
_blobCopyService = blobCopyService;
}

public Task<BlobFile> GetFileFromBlobStorage(string connectionString, string containerName, string fileName)
{
return _blobStorageHelper.GetFileFromBlobStorage(connectionString, containerName, fileName);
}

public Task<bool> CopyFileAsync(string connectionString, string fileName, string containerName)
{
return _blobCopyService.CopyFileAsync(connectionString, fileName, containerName);
}
}




[TestMethod]
public async Task GetFileFromBlobStorage_FileExists_ReturnsBlobFile()
{
// Arrange: Mock the wrapper instead of BlobStorageHelper
var mockBlobStorageHelper = new Mock<IBlobStorageHelperWrapper>();

string expectedFileName = "test-file.txt";
byte[] mockFileContent = Encoding.UTF8.GetBytes("This is a mock file content");

mockBlobStorageHelper
.Setup(x => x.GetFileFromBlobStorage(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
.ReturnsAsync(new BlobFile(mockFileContent, expectedFileName));

var yourClassInstance = mockBlobStorageHelper.Object;

// Act
var result = await yourClassInstance.GetFileFromBlobStorage("mock-connection", "mock-container", expectedFileName);

// Assert
Assert.IsNotNull(result);
Assert.AreEqual(expectedFileName, result.FileName);
}




[TestMethod]
public async Task GetFileFromBlobStorage_FileDoesNotExist_ReturnsNull()
{
// Arrange: Mock the IBlobStorageHelperWrapper interface
var mockBlobStorageHelperWrapper = new Mock<IBlobStorageHelperWrapper>();

// Ensure the wrapper returns null for a non-existent file
mockBlobStorageHelperWrapper
.Setup(x => x.GetFileFromBlobStorage(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
.ReturnsAsync((BlobFile)null); // Simulating a file not found case

// Inject the mock wrapper instead of the real BlobStorageHelper
var wrapperInstance = mockBlobStorageHelperWrapper.Object;

// Act: Call the method on the mocked wrapper
var result = await wrapperInstance.GetFileFromBlobStorage("mock-connection", "mock-container", "nonexistent.txt");

// Assert: Ensure method returns null when file does not exist
Assert.IsNull(result);
}


[TestMethod]
public async Task CopyFileAsync_SuccessfulCopy_ReturnsTrue()
{
// Arrange: Mock the IBlobCopyService (Encapsulates Lines 18-50)
var mockBlobCopyService = new Mock<IBlobCopyService>();

// Simulate successful file copy
mockBlobCopyService
.Setup(x => x.CopyFileAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
.ReturnsAsync(true);

// Inject Mocked Dependencies
var mockLogger = new Mock<ILogger<BlobStorageHelper>>();
var blobStorageHelper = new BlobStorageHelper(mockLogger.Object);

// ✅ Inject into Wrapper (Fix: Now Accepts Both Dependencies)
var wrapper = new BlobStorageHelperWrapper(blobStorageHelper, mockBlobCopyService.Object);

// Act: Call CopyFileAsync (Triggers Mocked Logic)
var result = await wrapper.CopyFileAsync("mock-connection", "mock-file.txt", "mock-container");

// Assert: Ensure CopyFileAsync returns true
Assert.IsTrue(result);

// ✅ Verify that CopyFileAsync was called (Ensures Execution of Lines 18-50)
mockBlobCopyService.Verify(x => x.CopyFileAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()), Times.Once);
}




[TestMethod]
public async Task UploadFileToBlobStorage_UploadFails_ReturnFalse()
{
// Arrange
using var memoryStream = new MemoryStream();
var blobFile = new BlobFile(memoryStream, "test.txt");

_mockBlobClient
.Setup(m => m.UploadAsync(It.IsAny<Stream>(), It.IsAny<bool>(), It.IsAny<CancellationToken>()))
.ThrowsAsync(new RequestFailedException("Upload failed")); // Simulate failure

// Act
var result = await _blobStorageHelper.UploadFileToBlobStorage("UseDevelopmentStorage=true", "container", blobFile);

// Assert
Assert.IsFalse(result, "UploadFileToBlobStorage should return false when upload fails.");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="MSTest.TestAdapter" Version="3.8.2" />
<PackageReference Include="MSTest.TestFramework" Version="3.8.2" />
</ItemGroup>

<ItemGroup>
<Using Include="Microsoft.VisualStudio.TestTools.UnitTesting" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\..\application\CohortManager\src\Functions\Shared\Data\Database\Data.csproj" />
<ProjectReference Include="..\..\..\..\application\CohortManager\src\Functions\Shared\Common\Common.csproj" />
<ProjectReference Include="..\..\..\..\application\CohortManager\src\Functions\Shared\HealthChecks\HealthChecks.csproj" />
<ProjectReference Include="..\..\..\..\application\CohortManager\src\Functions\Shared\Model\Model.csproj" />
<ProjectReference Include="..\..\..\TestUtils\TestUtils.csproj" />
</ItemGroup>

</Project>