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:
Joseph Doherty
2026-01-19 16:54:35 -05:00
parent 1c546c111a
commit fbe58a81e4
33 changed files with 1790 additions and 298 deletions
@@ -1,4 +1,5 @@
using System.Windows.Input;
using JdeScoping.SecureStoreManager.Services;
namespace JdeScoping.SecureStoreManager.ViewModels;
@@ -8,13 +9,15 @@ namespace JdeScoping.SecureStoreManager.ViewModels;
public class SecretItemViewModel : ViewModelBase
{
private readonly string _actualValue;
private readonly IClipboardService _clipboardService;
private bool _isValueVisible;
private const string MaskedValue = "********";
public SecretItemViewModel(string key, string value)
public SecretItemViewModel(string key, string value, IClipboardService clipboardService)
{
Key = key;
_actualValue = value;
_clipboardService = clipboardService ?? throw new ArgumentNullException(nameof(clipboardService));
ToggleVisibilityCommand = new RelayCommand(ToggleVisibility);
CopyToClipboardCommand = new RelayCommand(CopyToClipboard);
}
@@ -60,10 +63,9 @@ public class SecretItemViewModel : ViewModelBase
public ICommand CopyToClipboardCommand { get; }
/// <summary>
/// Event raised when clipboard copy is requested.
/// The view subscribes to this to perform the actual clipboard operation.
/// Event raised when clipboard copy fails.
/// </summary>
public event Func<string, Task>? OnCopyToClipboard;
public event Action<string>? OnCopyFailed;
private void ToggleVisibility()
{
@@ -74,14 +76,11 @@ public class SecretItemViewModel : ViewModelBase
{
try
{
if (OnCopyToClipboard != null)
{
await OnCopyToClipboard(_actualValue);
}
await _clipboardService.SetTextAsync(_actualValue);
}
catch
catch (Exception ex)
{
// Clipboard operations can fail in some scenarios
OnCopyFailed?.Invoke($"Failed to copy to clipboard: {ex.Message}");
}
}
}