Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: refactor for unit test #97

Merged
merged 20 commits into from
May 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ jobs:
DEFAULT_BRANCH: main
DEFAULT_WORKSPACE: ./Notation.Plugin.AzureKeyVault
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
FILTER_REGEX_EXCLUDE: .*Tests/.*
build:
name: "Build"
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ build: ## builds binaries

.PHONY: test
test: ## run unit test
rm -rf $(BUILD_DIR)/TestResults
dotnet test $(TEST_PROJECT_DIR) --collect:"XPlat Code Coverage" --logger trx --results-directory $(BUILD_DIR)/TestResults

.PHONY: install
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.IO;
using System.Security.Cryptography.X509Certificates;
using Xunit;

namespace Notation.Plugin.AzureKeyVault.Certificate.Tests
{
public class CertificateBundleTests
{
[Fact]
public void Create_WithValidPemFile_ReturnsCertificates()
{
// Arrange
string pemFilePath = Path.Combine(Directory.GetCurrentDirectory(), "TestData", "rsa_2048.crt");

// Act
X509Certificate2Collection certificates = CertificateBundle.Create(pemFilePath);

// Assert
Assert.NotNull(certificates);
Assert.True(certificates.Count > 0);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using Notation.Plugin.Protocol;
using Xunit;

namespace Notation.Plugin.AzureKeyVault.Certificate.Tests
{
public class CertificateChainTests
{
[Fact]
public void Build_WithValidLeafAndCertificateBundle_BuildsCertificateChain()
{
// Arrange
X509Certificate2 leafCert = new X509Certificate2(Path.Combine(Directory.GetCurrentDirectory(), "TestData", "leaf.crt"));
X509Certificate2Collection certificateBundle = CertificateBundle.Create(Path.Combine(Directory.GetCurrentDirectory(), "TestData", "root.crt"));

// Act
List<byte[]> certificateChain = CertificateChain.Build(leafCert, certificateBundle);

// Assert
Assert.NotNull(certificateChain);
Assert.True(certificateChain.Count > 0);
}

[Fact]
public void Build_WithInvalidLeafCertificate_ThrowsValidationException()
{
// Arrange
X509Certificate2 expiredLeafCert = new X509Certificate2(Path.Combine(Directory.GetCurrentDirectory(), "TestData", "expired_leaf.crt"));
X509Certificate2Collection certificateBundle = new X509Certificate2Collection();

// Act and Assert
Assert.Throws<ValidationException>(() => CertificateChain.Build(expiredLeafCert, certificateBundle));
}

[Fact]
public void Build_WithIncompleteCertificateBundle_ThrowsValidationException()
{
// Arrange
X509Certificate2 invalidLeafCert = new X509Certificate2(Path.Combine(Directory.GetCurrentDirectory(), "TestData", "leaf.crt"));
X509Certificate2Collection certificateBundle = new X509Certificate2Collection();

// Act and Assert
Assert.Throws<ValidationException>(() => CertificateChain.Build(invalidLeafCert, certificateBundle));
}
}
}
61 changes: 61 additions & 0 deletions Notation.Plugin.AzureKeyVault.Tests/Command/DescribeKeyTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using Moq;
using Notation.Plugin.AzureKeyVault.Client;
using Notation.Plugin.Protocol;
using Xunit;

namespace Notation.Plugin.AzureKeyVault.Command.Tests
{
public class DescribeKeyTests
{
[Fact]
public async Task RunAsync_ReturnsValidDescribeKeyResponseAsync()
{
// Arrange
var keyId = "https://testvault.vault.azure.net/keys/testkey/123";
var expectedKeySpec = "RSA-2048";
var mockCert = new X509Certificate2(Path.Combine(Directory.GetCurrentDirectory(), "TestData", "rsa_2048.crt"));

var mockKeyVaultClient = new Mock<IKeyVaultClient>();
mockKeyVaultClient.Setup(client => client.GetCertificateAsync()).ReturnsAsync(mockCert);

var request = new DescribeKeyRequest(contractVersion: "1.0", keyId);
var describeKeyCommand = new DescribeKey(request, mockKeyVaultClient.Object);

// Act
var result = await describeKeyCommand.RunAsync();

// Assert
Assert.IsType<DescribeKeyResponse>(result);
var response = result as DescribeKeyResponse;
if (response == null)
{
throw new System.Exception("response is null");
}
Assert.Equal(keyId, response.KeyId);
Assert.Equal(expectedKeySpec, response.KeySpec);
}

[Fact]
public void Constructor_ThrowsValidationException_WhenInvalidInput()
{
// Arrange
string invalidInputJson = "null";

// Act & Assert
Assert.Throws<ValidationException>(() => new DescribeKey(invalidInputJson));
}

[Fact]
public void Constructor_Valid()
{
// Arrange
string validInputJson = "{\"contractVersion\":\"1.0\",\"keyId\":\"https://notationakvtest.vault.azure.net/keys/dotnetPluginCertPKCS12/3f06c6eeac0640ea9f93cd0bf69d2f17\"}";

// Act & Assert
Assert.Null(Record.Exception(() => new DescribeKey(validInputJson)));
}
}
}
171 changes: 171 additions & 0 deletions Notation.Plugin.AzureKeyVault.Tests/Command/GenerateSignatureTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using Azure.Security.KeyVault.Keys.Cryptography;
using Moq;
using Notation.Plugin.AzureKeyVault.Certificate;
using Notation.Plugin.AzureKeyVault.Client;
using Notation.Plugin.Protocol;
using Xunit;

namespace Notation.Plugin.AzureKeyVault.Command.Tests
{
public class GenerateSignatureTests
{
[Fact]
public async Task RunAsync_SelfSigned_ReturnsValidGenerateSignatureResponseAsync()
{
// Arrange
var keyId = "https://testvault.vault.azure.net/keys/testkey/123";
var expectedKeySpec = "RSA-2048";
var mockCert = new X509Certificate2(Path.Combine(Directory.GetCurrentDirectory(), "TestData", "rsa_2048.crt"));
var mockSignature = new byte[] { 0x01, 0x02, 0x03, 0x04 };

var mockKeyVaultClient = new Mock<IKeyVaultClient>();
// mock GetCertificateAsync
mockKeyVaultClient.Setup(client => client.GetCertificateAsync())
.ReturnsAsync(mockCert);

// mock SignAsync
mockKeyVaultClient.Setup(client => client.SignAsync(It.IsAny<SignatureAlgorithm>(), It.IsAny<byte[]>()))
.ReturnsAsync(mockSignature);

var request = new GenerateSignatureRequest(
contractVersion: "1.0",
keyId: keyId,
pluginConfig: null,
keySpec: expectedKeySpec,
hashAlgorithm: "SHA-256",
payload: Encoding.UTF8.GetBytes("Cg=="));

var generateSignatureCommand = new GenerateSignature(request, mockKeyVaultClient.Object);

var result = await generateSignatureCommand.RunAsync();

Assert.IsType<GenerateSignatureResponse>(result);
var response = result as GenerateSignatureResponse;
if (response == null)
{
throw new System.Exception("response is null");
}
Assert.Equal(keyId, response.KeyId);
Assert.Equal("RSASSA-PSS-SHA-256", response.SigningAlgorithm);
Assert.Equal(mockSignature, response.Signature);
Assert.Single(response.CertificateChain);
Assert.Equal(mockCert.RawData, response.CertificateChain[0]);
}

[Fact]
public async Task RunAsync_ca_certs_ReturnsValidGenerateSignatureResponseAsync()
{
// Arrange
var keyId = "https://testvault.vault.azure.net/keys/testkey/123";
var expectedKeySpec = "RSA-2048";
var testRootCert = new X509Certificate2(Path.Combine(Directory.GetCurrentDirectory(), "TestData", "root.crt"));
var mockCert = new X509Certificate2(Path.Combine(Directory.GetCurrentDirectory(), "TestData", "leaf.crt"));
var mockSignature = new byte[] { 0x01, 0x02, 0x03, 0x04 };

var mockKeyVaultClient = new Mock<IKeyVaultClient>();
// mock GetCertificateAsync
mockKeyVaultClient.Setup(client => client.GetCertificateAsync())
.ReturnsAsync(mockCert);

// mock SignAsync
mockKeyVaultClient.Setup(client => client.SignAsync(It.IsAny<SignatureAlgorithm>(), It.IsAny<byte[]>()))
.ReturnsAsync(mockSignature);

var request = new GenerateSignatureRequest(
contractVersion: "1.0",
keyId: keyId,
pluginConfig: new Dictionary<string, string>()
{
["ca_certs"] = Path.Combine(Directory.GetCurrentDirectory(), "TestData", "root.crt")
},
keySpec: expectedKeySpec,
hashAlgorithm: "SHA-256",
payload: Encoding.UTF8.GetBytes("Cg=="));

var generateSignatureCommand = new GenerateSignature(request, mockKeyVaultClient.Object);

var result = await generateSignatureCommand.RunAsync();

Assert.IsType<GenerateSignatureResponse>(result);
var response = result as GenerateSignatureResponse;
if (response == null)
{
throw new System.Exception("response is null");
}
Assert.Equal(keyId, response.KeyId);
Assert.Equal("RSASSA-PSS-SHA-256", response.SigningAlgorithm);
Assert.Equal(mockSignature, response.Signature);
Assert.Equal(2, response.CertificateChain.Count);
Assert.Equal(mockCert.RawData, response.CertificateChain[0]);
Assert.Equal(testRootCert.RawData, response.CertificateChain[1]);
}

[Fact]
public async Task RunAsync_as_secret_ReturnsValidGenerateSignatureResponseAsync()
{
// Arrange
var keyId = "https://testvault.vault.azure.net/keys/testkey/123";
var expectedKeySpec = "RSA-2048";
var mockSignature = new byte[] { 0x01, 0x02, 0x03, 0x04 };
var mockCertChain = CertificateBundle.Create(Path.Combine(Directory.GetCurrentDirectory(), "TestData", "cert_chain.pem"));

var mockKeyVaultClient = new Mock<IKeyVaultClient>();
// mock GetCertificateAsync
mockKeyVaultClient.Setup(client => client.GetCertificateChainAsync())
.ReturnsAsync(mockCertChain);

// mock SignAsync
mockKeyVaultClient.Setup(client => client.SignAsync(It.IsAny<SignatureAlgorithm>(), It.IsAny<byte[]>()))
.ReturnsAsync(mockSignature);

var request = new GenerateSignatureRequest(
contractVersion: "1.0",
keyId: keyId,
pluginConfig: new Dictionary<string, string>()
{
["as_secret"] = "true"
},
keySpec: expectedKeySpec,
hashAlgorithm: "SHA-256",
payload: Encoding.UTF8.GetBytes("Cg=="));

var generateSignatureCommand = new GenerateSignature(request, mockKeyVaultClient.Object);

var result = await generateSignatureCommand.RunAsync();

Assert.IsType<GenerateSignatureResponse>(result);
var response = result as GenerateSignatureResponse;
if (response == null)
{
throw new System.Exception("response is null");
}
Assert.Equal(keyId, response.KeyId);
Assert.Equal("RSASSA-PSS-SHA-256", response.SigningAlgorithm);
Assert.Equal(mockSignature, response.Signature);
Assert.Equal(2, response.CertificateChain.Count);
Assert.Equal(mockCertChain[0].RawData, response.CertificateChain[0]);
Assert.Equal(mockCertChain[1].RawData, response.CertificateChain[1]);
}

[Fact]
public void Constructor_Valid()
{
string validInputJson = "{\"contractVersion\":\"1.0\",\"keyId\":\"https://notationakvtest.vault.azure.net/keys/dotnetPluginCert/b6046b30d069458886de94b0ac9ed121\",\"keySpec\":\"RSA-2048\",\"hashAlgorithm\":\"SHA-256\",\"payload\":\"Cg==\"}";

Assert.Null(Record.Exception(() => new GenerateSignature(validInputJson)));
}

[Fact]
public void Constructor_Invalid()
{
string InvalidInputJson = "null";

Assert.Throws<ValidationException>(() => new GenerateSignature(InvalidInputJson));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Threading.Tasks;
using Xunit;
using Notation.Plugin.Protocol;
using Xunit;

namespace Notation.Plugin.AzureKeyVault.Command.Tests
{
Expand All @@ -13,7 +13,7 @@ public async Task RunAsync_ReturnsExpectedMetadata()
var getPluginMetadata = new GetPluginMetadata();

// Act
var result = await getPluginMetadata.RunAsync("");
var result = await getPluginMetadata.RunAsync();

// Assert
Assert.IsType<GetMetadataResponse>(result);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System;
using Notation.Plugin.Protocol;
using Xunit;

namespace Notation.Plugin.AzureKeyVault.Client.Tests
{
public class KeySpecExtensionTests
{
[Theory]
[InlineData(KeyType.RSA, 2048, "PS256")]
[InlineData(KeyType.RSA, 3072, "PS384")]
[InlineData(KeyType.RSA, 4096, "PS512")]
[InlineData(KeyType.EC, 256, "ES256")]
[InlineData(KeyType.EC, 384, "ES384")]
[InlineData(KeyType.EC, 521, "ES512")]
public void ToSignatureAlgorithm_ValidKeySpecs_ReturnsCorrectSignatureAlgorithm(KeyType keyType, int keySize, string expectedAlgorithm)
{
// Arrange
var keySpec = new KeySpec(keyType, keySize);
// Act
var signatureAlgorithm = keySpec.ToKeyVaultSignatureAlgorithm();

// Assert
Assert.Equal(expectedAlgorithm, signatureAlgorithm);
}

[Theory]
[InlineData(KeyType.RSA, 1024)]
[InlineData(KeyType.EC, 128)]
public void ToSignatureAlgorithm_InvalidKeySpecs_ThrowsArgumentException(KeyType keyType, int keySize)
{
// Arrange
var keySpec = new KeySpec(keyType, keySize);

// Act & Assert
Assert.Throws<ArgumentException>(() => keySpec.ToKeyVaultSignatureAlgorithm());
}
}
}