using Microsoft.VisualStudio.TestTools.UnitTesting; using Strata.Base.Internal.Encryptors; using System; using System.Configuration; using System.Text; namespace Strata.Base.Internal.Tests.Security { [TestClass] public class UserSaltEncryptionMethodTests { private const string TestUsername = "testuser"; private const string TestOrgPin = "12345"; private const string TestPassword = "password123"; private static readonly Guid TestUserGuid = Guid.NewGuid(); private const string TestSalt = "testsalt"; private const string TestKey = "TestKey123"; [TestInitialize] public void Setup() { // Set up the configuration key for testing var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); config.AppSettings.Settings.Remove("UserSaltEncryptionKey"); config.AppSettings.Settings.Add("UserSaltEncryptionKey", TestKey); config.Save(); ConfigurationManager.RefreshSection("appSettings"); } [TestMethod] public void Encode_ReturnsNonEmptyString() { // Arrange var encryptor = new UserSaltEncryptionMethod(); // Act string result = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, TestSalt); // Assert Assert.IsFalse(string.IsNullOrEmpty(result), "Encoded result should not be empty"); } [TestMethod] public void Encode_SameInputProducesSameOutput() { // Arrange var encryptor = new UserSaltEncryptionMethod(); // Act string result1 = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, TestSalt); string result2 = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, TestSalt); // Assert Assert.AreEqual(result1, result2, "Same input should produce same hash"); } [TestMethod] public void Encode_DifferentPasswordsProduceDifferentOutputs() { // Arrange var encryptor = new UserSaltEncryptionMethod(); string differentPassword = "differentpassword123"; // Act string result1 = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, TestSalt); string result2 = encryptor.Encode(TestUsername, TestOrgPin, differentPassword, TestUserGuid, TestSalt); // Assert Assert.AreNotEqual(result1, result2, "Different passwords should produce different hashes"); } [TestMethod] public void Encode_DifferentSaltsProduceDifferentOutputs() { // Arrange var encryptor = new UserSaltEncryptionMethod(); string differentSalt = "differentsalt"; // Act string result1 = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, TestSalt); string result2 = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, differentSalt); // Assert Assert.AreNotEqual(result1, result2, "Different salts should produce different hashes"); } [TestMethod] public void Encode_OutputIsBase64String() { // Arrange var encryptor = new UserSaltEncryptionMethod(); // Act string result = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, TestSalt); // Assert try { Convert.FromBase64String(result); } catch (Exception ex) { Assert.Fail($"Result should be a valid Base64 string. Error: {ex.Message}"); } } [TestMethod] public void Encode_OutputHasExpectedLength() { // Arrange var encryptor = new UserSaltEncryptionMethod(); // Act string result = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, TestSalt); byte[] decodedBytes = Convert.FromBase64String(result); // Assert Assert.AreEqual(24, decodedBytes.Length, "Output should be 24 bytes (192 bits)"); } [TestMethod] public void Encode_WithEmptyPassword_ReturnsValidHash() { // Arrange var encryptor = new UserSaltEncryptionMethod(); // Act string result = encryptor.Encode(TestUsername, TestOrgPin, "", TestUserGuid, TestSalt); // Assert Assert.IsFalse(string.IsNullOrEmpty(result), "Empty password should still produce a hash"); Assert.AreEqual(24, Convert.FromBase64String(result).Length, "Hash should still be 24 bytes"); } [TestMethod] public void Encode_WithEmptySalt_ReturnsValidHash() { // Arrange var encryptor = new UserSaltEncryptionMethod(); // Act string result = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, ""); // Assert Assert.IsFalse(string.IsNullOrEmpty(result), "Empty salt should still produce a hash"); Assert.AreEqual(24, Convert.FromBase64String(result).Length, "Hash should still be 24 bytes"); } [TestMethod] public void Encode_WithLongPassword_HandlesCorrectly() { // Arrange var encryptor = new UserSaltEncryptionMethod(); string longPassword = new string('a', 1000000); // 1MB password // Act string result = encryptor.Encode(TestUsername, TestOrgPin, longPassword, TestUserGuid, TestSalt); // Assert Assert.IsFalse(string.IsNullOrEmpty(result), "Long password should produce a hash"); Assert.AreEqual(24, Convert.FromBase64String(result).Length, "Hash should still be 24 bytes"); } [TestMethod] public void Encode_WithLongSalt_HandlesCorrectly() { // Arrange var encryptor = new UserSaltEncryptionMethod(); string longSalt = new string('a', 1000000); // 1MB salt // Act string result = encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, longSalt); // Assert Assert.IsFalse(string.IsNullOrEmpty(result), "Long salt should produce a hash"); Assert.AreEqual(24, Convert.FromBase64String(result).Length, "Hash should still be 24 bytes"); } [TestMethod] public void Encode_WithSpecialCharacters_HandlesCorrectly() { // Arrange var encryptor = new UserSaltEncryptionMethod(); string specialCharsPassword = "!@#$%^&*()_+-=[]{}|;:'\",.<>?/~`"; string specialCharsSalt = "!@#$%^&*()_+-=[]{}|;:'\",.<>?/~`"; // Act string result = encryptor.Encode(TestUsername, TestOrgPin, specialCharsPassword, TestUserGuid, specialCharsSalt); // Assert Assert.IsFalse(string.IsNullOrEmpty(result), "Special characters should produce a hash"); Assert.AreEqual(24, Convert.FromBase64String(result).Length, "Hash should still be 24 bytes"); } [TestMethod] public void Encode_WithUnicodeCharacters_HandlesCorrectly() { // Arrange var encryptor = new UserSaltEncryptionMethod(); string unicodePassword = "Hello 世界! Привет мир! 안녕하세요!"; string unicodeSalt = "Salt 世界! Соль! 소금!"; // Act string result = encryptor.Encode(TestUsername, TestOrgPin, unicodePassword, TestUserGuid, unicodeSalt); // Assert Assert.IsFalse(string.IsNullOrEmpty(result), "Unicode characters should produce a hash"); Assert.AreEqual(24, Convert.FromBase64String(result).Length, "Hash should still be 24 bytes"); } [TestMethod] public void Encode_WithNullSalt_ThrowsArgumentNullException() { // Arrange var encryptor = new UserSaltEncryptionMethod(); // Assert Assert.ThrowsException(() => encryptor.Encode(TestUsername, TestOrgPin, TestPassword, TestUserGuid, null)); } [TestMethod] public void Encode_WithNullPassword_ThrowsArgumentNullException() { // Arrange var encryptor = new UserSaltEncryptionMethod(); // Assert Assert.ThrowsException(() => encryptor.Encode(TestUsername, TestOrgPin, null, TestUserGuid, TestSalt)); } [TestMethod] public void Encode_WithNullUsername_ThrowsArgumentNullException() { // Arrange var encryptor = new UserSaltEncryptionMethod(); // Assert Assert.ThrowsException(() => encryptor.Encode(null, TestOrgPin, TestPassword, TestUserGuid, TestSalt)); } [TestMethod] public void Encode_WithNullOrgPin_ThrowsArgumentNullException() { // Arrange var encryptor = new UserSaltEncryptionMethod(); // Assert Assert.ThrowsException(() => encryptor.Encode(TestUsername, null, TestPassword, TestUserGuid, TestSalt)); } } }