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.
This commit is contained in:
+115
@@ -0,0 +1,115 @@
|
||||
using JdeScoping.ConfigManager.ViewModels.Forms;
|
||||
|
||||
namespace JdeScoping.ConfigManager.Tests.ViewModels.Forms;
|
||||
|
||||
public class SecureStoreLockedFormViewModelTests
|
||||
{
|
||||
[Fact]
|
||||
public void Constructor_SetsPropertiesCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
var lastModified = DateTime.Now;
|
||||
|
||||
// Act
|
||||
var sut = new SecureStoreLockedFormViewModel(
|
||||
"test.secrets",
|
||||
"/path/to/test.secrets",
|
||||
lastModified,
|
||||
() => { });
|
||||
|
||||
// Assert
|
||||
sut.StoreName.ShouldBe("test.secrets");
|
||||
sut.StorePath.ShouldBe("/path/to/test.secrets");
|
||||
sut.LastModified.ShouldBe(lastModified);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_WithNullLastModified_SetsNullLastModified()
|
||||
{
|
||||
// Arrange & Act
|
||||
var sut = new SecureStoreLockedFormViewModel(
|
||||
"test.secrets",
|
||||
"/path/to/test.secrets",
|
||||
null,
|
||||
() => { });
|
||||
|
||||
// Assert
|
||||
sut.LastModified.ShouldBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnlockCommand_InvokesCallback()
|
||||
{
|
||||
// Arrange
|
||||
var unlockCalled = false;
|
||||
var sut = new SecureStoreLockedFormViewModel(
|
||||
"test.secrets",
|
||||
"/path/to/test.secrets",
|
||||
null,
|
||||
() => unlockCalled = true);
|
||||
|
||||
// Act
|
||||
sut.UnlockCommand.Execute(null);
|
||||
|
||||
// Assert
|
||||
unlockCalled.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnlockCommand_CanExecute_ReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecureStoreLockedFormViewModel(
|
||||
"test.secrets",
|
||||
"/path/to/test.secrets",
|
||||
null,
|
||||
() => { });
|
||||
|
||||
// Act & Assert
|
||||
sut.UnlockCommand.CanExecute(null).ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_ThrowsOnNullStoreName()
|
||||
{
|
||||
// Act & Assert
|
||||
Should.Throw<ArgumentNullException>(() =>
|
||||
new SecureStoreLockedFormViewModel(null!, "/path", null, () => { }));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_ThrowsOnNullStorePath()
|
||||
{
|
||||
// Act & Assert
|
||||
Should.Throw<ArgumentNullException>(() =>
|
||||
new SecureStoreLockedFormViewModel("test", null!, null, () => { }));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_ThrowsOnNullUnlockCallback()
|
||||
{
|
||||
// Act & Assert
|
||||
Should.Throw<ArgumentNullException>(() =>
|
||||
new SecureStoreLockedFormViewModel("test", "/path", null, null!));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Properties_AreReadOnly()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecureStoreLockedFormViewModel(
|
||||
"test.secrets",
|
||||
"/path/to/test.secrets",
|
||||
DateTime.Now,
|
||||
() => { });
|
||||
|
||||
// Assert - Verify properties are get-only (no setters)
|
||||
var storeNameProperty = typeof(SecureStoreLockedFormViewModel).GetProperty(nameof(SecureStoreLockedFormViewModel.StoreName));
|
||||
var storePathProperty = typeof(SecureStoreLockedFormViewModel).GetProperty(nameof(SecureStoreLockedFormViewModel.StorePath));
|
||||
var lastModifiedProperty = typeof(SecureStoreLockedFormViewModel).GetProperty(nameof(SecureStoreLockedFormViewModel.LastModified));
|
||||
|
||||
storeNameProperty!.CanWrite.ShouldBeFalse();
|
||||
storePathProperty!.CanWrite.ShouldBeFalse();
|
||||
lastModifiedProperty!.CanWrite.ShouldBeFalse();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user