Skip to content

Commit

Permalink
#127 test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
maythamfahmi committed Nov 23, 2024
1 parent 1fea66a commit 11b0b53
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 23 deletions.
126 changes: 115 additions & 11 deletions CryptoNet.UnitTests/CryptoNetRsaTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
using System.IO;
using System.Linq;
using Moq;
using System.Reflection;
using Moq.Protected;
using Microsoft.VisualStudio.TestPlatform.Common.Utilities;


// ReSharper disable All
Expand Down Expand Up @@ -124,6 +127,34 @@ public void Encrypt_Decrypt_Documents_With_SelfGenerated_AsymmetricKey_That_Is_S
ClassicAssert.AreEqual(testDocument, decrypt);
}

[Test]
public void Encrypt_Documents_With_SelfGenerated_AsymmetricKey_That_Is_Null()
{
// Arrange
try
{
new CryptoNetRsa(new FileInfo(PublicKeyFile)).EncryptFromBytes(new byte[0]);
}
catch (Exception e)
{
e.Message.ShouldStartWith("Value cannot be null.");
}
}

[Test]
public void Decrypt_Documents_With_SelfGenerated_AsymmetricKey_That_Is_Null()
{
// Arrange
try
{
new CryptoNetRsa(new FileInfo(PublicKeyFile)).DecryptToBytes(new byte[0]);
}
catch (Exception e)
{
e.Message.ShouldStartWith("Value cannot be null.");
}
}

[Test]
public void Encrypt_Decrypt_Content_With_PreStored_SelfGenerated_AsymmetricKey_Test()
{
Expand Down Expand Up @@ -207,7 +238,7 @@ public void Encrypt_Decrypt_Using_X509_Certificate_Test()
{
// Arrange
// You can change to test real system certificate by using CryptoNetExtensions.GetCertificateFromStore("CN=MaythamCertificateName")
X509Certificate2 ? certificate = TestConfig.CreateSelfSignedCertificate();
X509Certificate2? certificate = TestConfig.CreateSelfSignedCertificate();
var rsaPublicKey = new CryptoNetRsa(certificate, KeyType.PublicKey);
var rsaPrivateKey = new CryptoNetRsa(certificate, KeyType.PrivateKey);

Expand Down Expand Up @@ -264,20 +295,40 @@ public void Customize_PEM_Key_Encryption_Decryption_Test()
TestConfig.ConfidentialDummyData.ShouldBe(decryptedData2);
}

[Ignore("")]
public void SaveKey_ShouldInvokeSaveKeyWithFileInfo_WhenGivenFilename()
[Test]
public void CheckKeyType_ShouldReturnNotSet_WhenExceptionOccurs()
{
// Arrange
var filename = "testfile.txt";
Mock<RSA> _rsaMock = new Mock<RSA>();

// Create a mock for the KeySaver class if SaveKey(FileInfo) is not directly testable
var keySaverMock = new Mock<CryptoNetRsa>() { CallBase = true }; // Assuming KeySaver is not static
CryptoNetRsa _cryptoNetRsa = new CryptoNetRsa(2048);

// Act
keySaverMock.Object.SaveKey(filename);
// Access the private field 'Rsa' using reflection and set it to the mocked RSA
var rsaField = typeof(CryptoNetRsa).GetField("<Rsa>k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance);
if (rsaField != null)
{
rsaField.SetValue(_cryptoNetRsa, _rsaMock.Object);
}

// Assert
keySaverMock.Verify(saver => saver.SaveKey(It.Is<FileInfo>(fi => fi.FullName == filename), false), Times.Once);
_rsaMock.Setup(r => r.ExportParameters(true)).Throws(new Exception());

MethodInfo? methodInfo = typeof(CryptoNetRsa).GetMethod("CheckKeyType", BindingFlags.NonPublic | BindingFlags.Instance);
methodInfo.ShouldNotBeNull();

var result = methodInfo.Invoke(_cryptoNetRsa, null);

result.ShouldBe(KeyType.NotSet);
}

[Test]
public void SaveKey_ShouldCallSaveKeyWithFileInfo_WhenGivenFilename()
{
string TestFilePath = "testfilex.txt";
string TestContent = "<RSAKeyValue><Modulus>";

var rsa = new CryptoNetRsa(2048);
rsa.SaveKey(TestFilePath, false);
var savedContent = File.ReadAllText(TestFilePath);
savedContent.ShouldStartWith(TestContent);
}

public static ICryptoNetRsa ImportPemKey(char[] key)
Expand All @@ -287,6 +338,59 @@ public static ICryptoNetRsa ImportPemKey(char[] key)
return cryptoNet;
}

[Test]
public void ExportKey_ShouldReturnEmptyString_WhenKeyTypeIsNotSet()
{
Mock<RSA> _rsaMock = new Mock<RSA>();
Mock<CryptoNetRsa> _cryptoNetRsaMock = new Mock<CryptoNetRsa>(MockBehavior.Default, 2048);
_cryptoNetRsaMock.CallBase = true; // Call the base methods as well

// Inject the mocked RSA instance
FieldInfo? rsaField = typeof(CryptoNetRsa).GetField("<Rsa>k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance);
if (rsaField != null)
{
rsaField.SetValue(_cryptoNetRsaMock.Object, _rsaMock.Object);
}

// Arrange
var keyType = KeyType.NotSet;

// Use reflection to invoke the private ExportKey method
MethodInfo? methodInfo = typeof(CryptoNetRsa).GetMethod("ExportKey", BindingFlags.NonPublic | BindingFlags.Instance);
methodInfo.ShouldNotBeNull();

// Act: Invoke the private method via reflection
var result = methodInfo.Invoke(_cryptoNetRsaMock.Object, new object[] { keyType });

// Assert
result.ShouldBe(string.Empty);
}

[Test]
public void ExportKey_ShouldThrowException_WhenKeyTypeIsNotSet()
{
Mock<RSA> _rsaMock = new Mock<RSA>();
Mock<CryptoNetRsa> _cryptoNetRsaMock = new Mock<CryptoNetRsa>(MockBehavior.Default, 2048);
_cryptoNetRsaMock.CallBase = true; // Call the base methods as well

// Inject the mocked RSA instance
FieldInfo? rsaField = typeof(CryptoNetRsa).GetField("<Rsa>k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance);
if (rsaField != null)
{
rsaField.SetValue(_cryptoNetRsaMock.Object, _rsaMock.Object);
}

// Arrange
var keyType = (KeyType)999; // Invalid KeyType

// Use reflection to invoke the private method
MethodInfo? methodInfo = typeof(CryptoNetRsa).GetMethod("ExportKey", BindingFlags.NonPublic | BindingFlags.Instance);
methodInfo.ShouldNotBeNull();

// Act & Assert
Should.Throw<Exception>(() => methodInfo.Invoke(_cryptoNetRsaMock.Object, new object[] { keyType }));
}

public static ICryptoNetRsa ImportPemKeyWithPassword(byte[] encryptedPrivateKey, string password)
{
ICryptoNetRsa cryptoNet = new CryptoNetRsa();
Expand Down
24 changes: 12 additions & 12 deletions CryptoNet/CryptoNetRsa.cs
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,14 @@ public byte[] EncryptFromString(string content)
/// </summary>
/// <param name="bytes">The byte array to encrypt.</param>
/// <returns>The encrypted byte array.</returns>
/// <exception cref="ArgumentNullException">Thrown when the input byte array is null or empty.</exception>
public byte[] EncryptFromBytes(byte[] bytes)
{
if (bytes == null || bytes.Length <= 0)
{
throw new ArgumentNullException(nameof(bytes));
}

return EncryptContent(bytes);
}

Expand All @@ -254,8 +260,14 @@ public string DecryptToString(byte[] bytes)
/// </summary>
/// <param name="bytes">The encrypted byte array to decrypt.</param>
/// <returns>The decrypted byte array.</returns>
/// <exception cref="ArgumentNullException">Thrown when the input byte array is null or empty.</exception>
public byte[] DecryptToBytes(byte[] bytes)
{
if (bytes == null || bytes.Length <= 0)
{
throw new ArgumentNullException(nameof(bytes));
}

return DecryptContent(bytes);
}

Expand All @@ -264,14 +276,8 @@ public byte[] DecryptToBytes(byte[] bytes)
/// </summary>
/// <param name="bytes">The byte array to encrypt.</param>
/// <returns>The encrypted byte array.</returns>
/// <exception cref="ArgumentNullException">Thrown when the input byte array is null or empty.</exception>
private byte[] EncryptContent(byte[] bytes)
{
if (bytes == null || bytes.Length <= 0)
{
throw new ArgumentNullException(nameof(bytes));
}

byte[] result;

var aes = Aes.Create();
Expand Down Expand Up @@ -329,14 +335,8 @@ private byte[] EncryptContent(byte[] bytes)
/// </summary>
/// <param name="bytes">The encrypted byte array to decrypt.</param>
/// <returns>The decrypted byte array.</returns>
/// <exception cref="ArgumentNullException">Thrown when the input byte array is null or empty.</exception>
private byte[] DecryptContent(byte[] bytes)
{
if (bytes == null || bytes.Length <= 0)
{
throw new ArgumentNullException(nameof(bytes));
}

byte[] result;

var aes = Aes.Create();
Expand Down

0 comments on commit 11b0b53

Please sign in to comment.