refactor(securestoremanager): add platform service abstractions and constants
Implement deferred code review findings: - Add IDialogService/IClipboardService interfaces for testable platform operations - Create AvaloniaDialogService and AvaloniaClipboardService implementations - Extract dialog strings and file extensions to centralized Constants classes - Refactor ViewModels to use DI instead of event delegates - Update tests to use mock services
This commit is contained in:
+22
-19
@@ -1,16 +1,25 @@
|
||||
using NSubstitute;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
using JdeScoping.SecureStoreManager.Services;
|
||||
using JdeScoping.SecureStoreManager.ViewModels;
|
||||
|
||||
namespace JdeScoping.SecureStoreManager.Tests.ViewModels;
|
||||
|
||||
public class SecretItemViewModelTests
|
||||
{
|
||||
private readonly IClipboardService _mockClipboardService;
|
||||
|
||||
public SecretItemViewModelTests()
|
||||
{
|
||||
_mockClipboardService = Substitute.For<IClipboardService>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_InitializesKey()
|
||||
{
|
||||
// Arrange & Act
|
||||
var sut = new SecretItemViewModel("testKey", "testValue");
|
||||
var sut = new SecretItemViewModel("testKey", "testValue", _mockClipboardService);
|
||||
|
||||
// Assert
|
||||
sut.Key.ShouldBe("testKey");
|
||||
@@ -20,7 +29,7 @@ public class SecretItemViewModelTests
|
||||
public void Constructor_InitializesActualValue()
|
||||
{
|
||||
// Arrange & Act
|
||||
var sut = new SecretItemViewModel("testKey", "testValue");
|
||||
var sut = new SecretItemViewModel("testKey", "testValue", _mockClipboardService);
|
||||
|
||||
// Assert
|
||||
sut.ActualValue.ShouldBe("testValue");
|
||||
@@ -30,7 +39,7 @@ public class SecretItemViewModelTests
|
||||
public void Constructor_InitializesIsValueVisibleToFalse()
|
||||
{
|
||||
// Arrange & Act
|
||||
var sut = new SecretItemViewModel("testKey", "testValue");
|
||||
var sut = new SecretItemViewModel("testKey", "testValue", _mockClipboardService);
|
||||
|
||||
// Assert
|
||||
sut.IsValueVisible.ShouldBeFalse();
|
||||
@@ -40,7 +49,7 @@ public class SecretItemViewModelTests
|
||||
public void DisplayValue_WhenNotVisible_ReturnsMaskedValue()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretItemViewModel("testKey", "testValue");
|
||||
var sut = new SecretItemViewModel("testKey", "testValue", _mockClipboardService);
|
||||
|
||||
// Act & Assert
|
||||
sut.DisplayValue.ShouldBe("********");
|
||||
@@ -50,7 +59,7 @@ public class SecretItemViewModelTests
|
||||
public void DisplayValue_WhenVisible_ReturnsActualValue()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretItemViewModel("testKey", "testValue");
|
||||
var sut = new SecretItemViewModel("testKey", "testValue", _mockClipboardService);
|
||||
|
||||
// Act
|
||||
sut.IsValueVisible = true;
|
||||
@@ -63,7 +72,7 @@ public class SecretItemViewModelTests
|
||||
public void ToggleVisibilityCommand_TogglesIsValueVisible()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretItemViewModel("testKey", "testValue");
|
||||
var sut = new SecretItemViewModel("testKey", "testValue", _mockClipboardService);
|
||||
sut.IsValueVisible.ShouldBeFalse();
|
||||
|
||||
// Act
|
||||
@@ -77,7 +86,7 @@ public class SecretItemViewModelTests
|
||||
public void ToggleVisibilityCommand_TogglesBackToHidden()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretItemViewModel("testKey", "testValue");
|
||||
var sut = new SecretItemViewModel("testKey", "testValue", _mockClipboardService);
|
||||
sut.IsValueVisible = true;
|
||||
|
||||
// Act
|
||||
@@ -88,16 +97,10 @@ public class SecretItemViewModelTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CopyToClipboardCommand_RaisesOnCopyToClipboardEvent()
|
||||
public async Task CopyToClipboardCommand_CallsClipboardService()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretItemViewModel("testKey", "secretPassword");
|
||||
string? copiedValue = null;
|
||||
sut.OnCopyToClipboard += value =>
|
||||
{
|
||||
copiedValue = value;
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
var sut = new SecretItemViewModel("testKey", "secretPassword", _mockClipboardService);
|
||||
|
||||
// Act
|
||||
sut.CopyToClipboardCommand.Execute(null);
|
||||
@@ -105,14 +108,14 @@ public class SecretItemViewModelTests
|
||||
// Assert - need to wait for async handler
|
||||
// Give the async void handler time to complete
|
||||
await Task.Delay(100);
|
||||
copiedValue.ShouldBe("secretPassword");
|
||||
await _mockClipboardService.Received(1).SetTextAsync("secretPassword");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsValueVisible_SetterRaisesPropertyChangedForIsValueVisible()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretItemViewModel("testKey", "testValue");
|
||||
var sut = new SecretItemViewModel("testKey", "testValue", _mockClipboardService);
|
||||
var propertyChangedRaised = false;
|
||||
sut.PropertyChanged += (s, e) =>
|
||||
{
|
||||
@@ -131,7 +134,7 @@ public class SecretItemViewModelTests
|
||||
public void IsValueVisible_SetterRaisesPropertyChangedForDisplayValue()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretItemViewModel("testKey", "testValue");
|
||||
var sut = new SecretItemViewModel("testKey", "testValue", _mockClipboardService);
|
||||
var propertyChangedRaised = false;
|
||||
sut.PropertyChanged += (s, e) =>
|
||||
{
|
||||
@@ -150,7 +153,7 @@ public class SecretItemViewModelTests
|
||||
public void IsValueVisible_SetToSameValue_DoesNotRaisePropertyChanged()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretItemViewModel("testKey", "testValue");
|
||||
var sut = new SecretItemViewModel("testKey", "testValue", _mockClipboardService);
|
||||
sut.IsValueVisible = false; // Already false, but explicitly set
|
||||
var propertyChangedRaised = false;
|
||||
sut.PropertyChanged += (s, e) =>
|
||||
|
||||
Reference in New Issue
Block a user