Files
jdescopingtool/NEW/tests/JdeScoping.ConfigManager.Tests/Services/SecureStore/SecureStoreManagerTests.cs
T
Joseph Doherty 94d5a864e0 feat(configmanager): integrate SecureStore for credential management
Add SecureStore integration to ConfigManager for secure handling of connection
strings and sensitive configuration values. Includes store/secret management
UI, encrypted .store file support, and comprehensive test coverage.
2026-01-20 02:51:16 -05:00

339 lines
9.6 KiB
C#

using System.IO;
using JdeScoping.ConfigManager.Services.SecureStore;
namespace JdeScoping.ConfigManager.Tests.Services.SecureStore;
public class SecureStoreManagerTests : IDisposable
{
private readonly string _testDirectory;
private readonly SecureStoreManager _sut;
public SecureStoreManagerTests()
{
_testDirectory = Path.Combine(Path.GetTempPath(), $"SecureStoreTests_{Guid.NewGuid():N}");
Directory.CreateDirectory(_testDirectory);
_sut = new SecureStoreManager();
}
public void Dispose()
{
_sut.Dispose();
if (Directory.Exists(_testDirectory))
{
Directory.Delete(_testDirectory, recursive: true);
}
}
[Fact]
public void IsStoreOpen_WhenNoStoreOpen_ReturnsFalse()
{
_sut.IsStoreOpen.ShouldBeFalse();
}
[Fact]
public void CurrentStorePath_WhenNoStoreOpen_ReturnsNull()
{
_sut.CurrentStorePath.ShouldBeNull();
}
[Fact]
public void HasUnsavedChanges_WhenNoStoreOpen_ReturnsFalse()
{
_sut.HasUnsavedChanges.ShouldBeFalse();
}
[Fact]
public void CreateStore_WithKeyFile_CreatesStoreAndKeyFile()
{
// Arrange
var storePath = Path.Combine(_testDirectory, "test.json");
var keyPath = Path.Combine(_testDirectory, "test.key");
// Act
_sut.CreateStore(storePath, keyPath);
// Assert
_sut.IsStoreOpen.ShouldBeTrue();
_sut.CurrentStorePath.ShouldBe(storePath);
File.Exists(storePath).ShouldBeTrue();
File.Exists(keyPath).ShouldBeTrue();
}
[Fact]
public void CreateStoreWithPassword_CreatesStore()
{
// Arrange
var storePath = Path.Combine(_testDirectory, "test.json");
// Act
_sut.CreateStoreWithPassword(storePath, "testpassword123");
// Assert
_sut.IsStoreOpen.ShouldBeTrue();
_sut.CurrentStorePath.ShouldBe(storePath);
File.Exists(storePath).ShouldBeTrue();
}
[Fact]
public void CreateStoreWithPassword_WithEmptyPassword_ThrowsArgumentException()
{
// Arrange
var storePath = Path.Combine(_testDirectory, "test.json");
// Act & Assert
Should.Throw<ArgumentException>(() => _sut.CreateStoreWithPassword(storePath, ""));
}
[Fact]
public void OpenStore_WithValidKeyFile_OpensStore()
{
// Arrange
var storePath = Path.Combine(_testDirectory, "test.json");
var keyPath = Path.Combine(_testDirectory, "test.key");
_sut.CreateStore(storePath, keyPath);
_sut.CloseStore();
// Act
_sut.OpenStore(storePath, keyPath);
// Assert
_sut.IsStoreOpen.ShouldBeTrue();
_sut.CurrentStorePath.ShouldBe(storePath);
}
[Fact]
public void OpenStore_WithNonExistentStore_ThrowsFileNotFoundException()
{
// Arrange
var storePath = Path.Combine(_testDirectory, "nonexistent.json");
var keyPath = Path.Combine(_testDirectory, "test.key");
// Act & Assert
Should.Throw<FileNotFoundException>(() => _sut.OpenStore(storePath, keyPath));
}
[Fact]
public void OpenStoreWithPassword_OpensStore()
{
// Arrange
var storePath = Path.Combine(_testDirectory, "test.json");
var password = "testpassword123";
_sut.CreateStoreWithPassword(storePath, password);
_sut.CloseStore();
// Act
_sut.OpenStoreWithPassword(storePath, password);
// Assert
_sut.IsStoreOpen.ShouldBeTrue();
}
[Fact]
public void CloseStore_ClosesOpenStore()
{
// Arrange
var storePath = Path.Combine(_testDirectory, "test.json");
var keyPath = Path.Combine(_testDirectory, "test.key");
_sut.CreateStore(storePath, keyPath);
// Act
_sut.CloseStore();
// Assert
_sut.IsStoreOpen.ShouldBeFalse();
_sut.CurrentStorePath.ShouldBeNull();
}
[Fact]
public void SetSecret_AddsSecretAndMarksUnsaved()
{
// Arrange
var storePath = Path.Combine(_testDirectory, "test.json");
var keyPath = Path.Combine(_testDirectory, "test.key");
_sut.CreateStore(storePath, keyPath);
_sut.Save(); // Save to clear unsaved flag
// Act
_sut.SetSecret("testKey", "testValue");
// Assert
_sut.HasUnsavedChanges.ShouldBeTrue();
_sut.GetKeys().ShouldContain("testKey");
}
[Fact]
public void GetSecret_ReturnsCorrectValue()
{
// Arrange
var storePath = Path.Combine(_testDirectory, "test.json");
var keyPath = Path.Combine(_testDirectory, "test.key");
_sut.CreateStore(storePath, keyPath);
_sut.SetSecret("testKey", "testValue");
// Act
var value = _sut.GetSecret("testKey");
// Assert
value.ShouldBe("testValue");
}
[Fact]
public void GetSecret_WhenKeyNotFound_ThrowsKeyNotFoundException()
{
// Arrange
var storePath = Path.Combine(_testDirectory, "test.json");
var keyPath = Path.Combine(_testDirectory, "test.key");
_sut.CreateStore(storePath, keyPath);
// Act & Assert
Should.Throw<KeyNotFoundException>(() => _sut.GetSecret("nonexistent"));
}
[Fact]
public void RemoveSecret_RemovesSecretAndMarksUnsaved()
{
// Arrange
var storePath = Path.Combine(_testDirectory, "test.json");
var keyPath = Path.Combine(_testDirectory, "test.key");
_sut.CreateStore(storePath, keyPath);
_sut.SetSecret("testKey", "testValue");
_sut.Save();
// Act
_sut.RemoveSecret("testKey");
// Assert
_sut.HasUnsavedChanges.ShouldBeTrue();
_sut.GetKeys().ShouldNotContain("testKey");
}
[Fact]
public void RemoveSecret_WhenKeyNotFound_ThrowsKeyNotFoundException()
{
// Arrange
var storePath = Path.Combine(_testDirectory, "test.json");
var keyPath = Path.Combine(_testDirectory, "test.key");
_sut.CreateStore(storePath, keyPath);
// Act & Assert
Should.Throw<KeyNotFoundException>(() => _sut.RemoveSecret("nonexistent"));
}
[Fact]
public void Save_PersistsSecretsToStore()
{
// Arrange
var storePath = Path.Combine(_testDirectory, "test.json");
var keyPath = Path.Combine(_testDirectory, "test.key");
_sut.CreateStore(storePath, keyPath);
_sut.SetSecret("testKey", "testValue");
// Act
_sut.Save();
_sut.CloseStore();
_sut.OpenStore(storePath, keyPath);
// Assert
_sut.GetKeys().ShouldContain("testKey");
_sut.GetSecret("testKey").ShouldBe("testValue");
}
[Fact]
public void Save_ClearsUnsavedChangesFlag()
{
// Arrange
var storePath = Path.Combine(_testDirectory, "test.json");
var keyPath = Path.Combine(_testDirectory, "test.key");
_sut.CreateStore(storePath, keyPath);
_sut.SetSecret("testKey", "testValue");
_sut.HasUnsavedChanges.ShouldBeTrue();
// Act
_sut.Save();
// Assert
_sut.HasUnsavedChanges.ShouldBeFalse();
}
[Fact]
public void GetKeys_ReturnsAllSecretKeys()
{
// Arrange
var storePath = Path.Combine(_testDirectory, "test.json");
var keyPath = Path.Combine(_testDirectory, "test.key");
_sut.CreateStore(storePath, keyPath);
_sut.SetSecret("key1", "value1");
_sut.SetSecret("key2", "value2");
_sut.SetSecret("key3", "value3");
// Act
var keys = _sut.GetKeys();
// Assert
keys.Count.ShouldBe(3);
keys.ShouldContain("key1");
keys.ShouldContain("key2");
keys.ShouldContain("key3");
}
[Fact]
public void GenerateKeyFile_CreatesNewKeyFile()
{
// Arrange
var keyPath = Path.Combine(_testDirectory, "generated.key");
// Act
_sut.GenerateKeyFile(keyPath);
// Assert
File.Exists(keyPath).ShouldBeTrue();
}
[Fact]
public void ExportKey_WhenNoStoreOpen_ThrowsInvalidOperationException()
{
// Arrange
var keyPath = Path.Combine(_testDirectory, "export.key");
// Act & Assert
Should.Throw<InvalidOperationException>(() => _sut.ExportKey(keyPath));
}
[Fact]
public void ExportKey_WhenStoreOpen_ExportsKey()
{
// Arrange
var storePath = Path.Combine(_testDirectory, "test.json");
var keyPath = Path.Combine(_testDirectory, "test.key");
var exportPath = Path.Combine(_testDirectory, "export.key");
_sut.CreateStore(storePath, keyPath);
// Act
_sut.ExportKey(exportPath);
// Assert
File.Exists(exportPath).ShouldBeTrue();
}
[Fact]
public void GetKeys_WhenNoStoreOpen_ThrowsInvalidOperationException()
{
// Act & Assert
Should.Throw<InvalidOperationException>(() => _sut.GetKeys());
}
[Fact]
public void SetSecret_WhenNoStoreOpen_ThrowsInvalidOperationException()
{
// Act & Assert
Should.Throw<InvalidOperationException>(() => _sut.SetSecret("key", "value"));
}
[Fact]
public void GetSecret_WhenNoStoreOpen_ThrowsInvalidOperationException()
{
// Act & Assert
Should.Throw<InvalidOperationException>(() => _sut.GetSecret("key"));
}
}