refactor(configmanager): rename UI project and split test projects
Rename ConfigManager to ConfigManager.Ui to match the Core/CLI/UI project structure, and split the monolithic test project into Core.Tests, Cli.Tests, and Ui.Tests to align with the source project organization.
This commit is contained in:
+241
@@ -0,0 +1,241 @@
|
||||
using JdeScoping.ConfigManager.Core.Services;
|
||||
using JdeScoping.ConfigManager.Ui.ViewModels.Dialogs;
|
||||
|
||||
namespace JdeScoping.ConfigManager.Ui.Tests.ViewModels.Dialogs;
|
||||
|
||||
public class DiffPreviewDialogViewModelTests
|
||||
{
|
||||
[Fact]
|
||||
public void Constructor_WithEmptyDiff_InitializesCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
var diff = new DiffResult
|
||||
{
|
||||
HasChanges = false,
|
||||
Lines = [],
|
||||
Insertions = 0,
|
||||
Deletions = 0
|
||||
};
|
||||
|
||||
// Act
|
||||
var sut = new DiffPreviewDialogViewModel(diff);
|
||||
|
||||
// Assert
|
||||
sut.Lines.Count.ShouldBe(0);
|
||||
sut.HasChanges.ShouldBeFalse();
|
||||
sut.Insertions.ShouldBe(0);
|
||||
sut.Deletions.ShouldBe(0);
|
||||
sut.Result.ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_WithChanges_PopulatesLines()
|
||||
{
|
||||
// Arrange
|
||||
var diff = new DiffResult
|
||||
{
|
||||
HasChanges = true,
|
||||
Lines =
|
||||
[
|
||||
new DiffLine { OldLineNumber = 1, NewLineNumber = 1, Text = "unchanged line", Type = DiffLineType.Unchanged },
|
||||
new DiffLine { OldLineNumber = 2, NewLineNumber = null, Text = "removed line", Type = DiffLineType.Removed },
|
||||
new DiffLine { OldLineNumber = null, NewLineNumber = 2, Text = "added line", Type = DiffLineType.Added }
|
||||
],
|
||||
Insertions = 1,
|
||||
Deletions = 1
|
||||
};
|
||||
|
||||
// Act
|
||||
var sut = new DiffPreviewDialogViewModel(diff);
|
||||
|
||||
// Assert
|
||||
sut.Lines.Count.ShouldBe(3);
|
||||
sut.HasChanges.ShouldBeTrue();
|
||||
sut.Insertions.ShouldBe(1);
|
||||
sut.Deletions.ShouldBe(1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SaveCommand_SetsResultTrue_AndInvokesRequestClose()
|
||||
{
|
||||
// Arrange
|
||||
var diff = CreateEmptyDiff();
|
||||
var sut = new DiffPreviewDialogViewModel(diff);
|
||||
var closeInvoked = false;
|
||||
sut.RequestClose = () => closeInvoked = true;
|
||||
|
||||
// Act
|
||||
sut.SaveCommand.Execute(null);
|
||||
|
||||
// Assert
|
||||
sut.Result.ShouldBeTrue();
|
||||
closeInvoked.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CancelCommand_SetsResultFalse_AndInvokesRequestClose()
|
||||
{
|
||||
// Arrange
|
||||
var diff = CreateEmptyDiff();
|
||||
var sut = new DiffPreviewDialogViewModel(diff);
|
||||
var closeInvoked = false;
|
||||
sut.RequestClose = () => closeInvoked = true;
|
||||
|
||||
// Act
|
||||
sut.CancelCommand.Execute(null);
|
||||
|
||||
// Assert
|
||||
sut.Result.ShouldBeFalse();
|
||||
closeInvoked.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SaveCommand_DoesNotThrow_WhenRequestCloseIsNull()
|
||||
{
|
||||
// Arrange
|
||||
var diff = CreateEmptyDiff();
|
||||
var sut = new DiffPreviewDialogViewModel(diff);
|
||||
sut.RequestClose = null;
|
||||
|
||||
// Act & Assert - Should not throw
|
||||
Should.NotThrow(() => sut.SaveCommand.Execute(null));
|
||||
sut.Result.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CancelCommand_DoesNotThrow_WhenRequestCloseIsNull()
|
||||
{
|
||||
// Arrange
|
||||
var diff = CreateEmptyDiff();
|
||||
var sut = new DiffPreviewDialogViewModel(diff);
|
||||
sut.RequestClose = null;
|
||||
|
||||
// Act & Assert - Should not throw
|
||||
Should.NotThrow(() => sut.CancelCommand.Execute(null));
|
||||
sut.Result.ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_ThrowsOnNullDiff()
|
||||
{
|
||||
// Act & Assert
|
||||
Should.Throw<ArgumentNullException>(() => new DiffPreviewDialogViewModel(null!));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Result_InitialValue_IsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var diff = CreateEmptyDiff();
|
||||
|
||||
// Act
|
||||
var sut = new DiffPreviewDialogViewModel(diff);
|
||||
|
||||
// Assert
|
||||
sut.Result.ShouldBeFalse();
|
||||
}
|
||||
|
||||
private static DiffResult CreateEmptyDiff()
|
||||
{
|
||||
return new DiffResult
|
||||
{
|
||||
HasChanges = false,
|
||||
Lines = [],
|
||||
Insertions = 0,
|
||||
Deletions = 0
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class DiffLineViewModelTests
|
||||
{
|
||||
[Fact]
|
||||
public void Constructor_UnchangedLine_SetsPropertiesCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
var line = new DiffLine
|
||||
{
|
||||
OldLineNumber = 5,
|
||||
NewLineNumber = 5,
|
||||
Text = "unchanged content",
|
||||
Type = DiffLineType.Unchanged
|
||||
};
|
||||
|
||||
// Act
|
||||
var sut = new DiffLineViewModel(line);
|
||||
|
||||
// Assert
|
||||
sut.OldLineNumber.ShouldBe("5");
|
||||
sut.NewLineNumber.ShouldBe("5");
|
||||
sut.Text.ShouldBe("unchanged content");
|
||||
sut.Type.ShouldBe(DiffLineType.Unchanged);
|
||||
sut.Background.ShouldBe("Transparent");
|
||||
sut.BorderColor.ShouldBe("Transparent");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_AddedLine_SetsGreenStyling()
|
||||
{
|
||||
// Arrange
|
||||
var line = new DiffLine
|
||||
{
|
||||
OldLineNumber = null,
|
||||
NewLineNumber = 10,
|
||||
Text = "new line",
|
||||
Type = DiffLineType.Added
|
||||
};
|
||||
|
||||
// Act
|
||||
var sut = new DiffLineViewModel(line);
|
||||
|
||||
// Assert
|
||||
sut.OldLineNumber.ShouldBe("");
|
||||
sut.NewLineNumber.ShouldBe("10");
|
||||
sut.Type.ShouldBe(DiffLineType.Added);
|
||||
sut.Background.ShouldBe("#1A3DD68C");
|
||||
sut.BorderColor.ShouldBe("#3DD68C");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_RemovedLine_SetsRedStyling()
|
||||
{
|
||||
// Arrange
|
||||
var line = new DiffLine
|
||||
{
|
||||
OldLineNumber = 7,
|
||||
NewLineNumber = null,
|
||||
Text = "deleted line",
|
||||
Type = DiffLineType.Removed
|
||||
};
|
||||
|
||||
// Act
|
||||
var sut = new DiffLineViewModel(line);
|
||||
|
||||
// Assert
|
||||
sut.OldLineNumber.ShouldBe("7");
|
||||
sut.NewLineNumber.ShouldBe("");
|
||||
sut.Type.ShouldBe(DiffLineType.Removed);
|
||||
sut.Background.ShouldBe("#1AFF6B6B");
|
||||
sut.BorderColor.ShouldBe("#FF6B6B");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_NullLineNumbers_ReturnsEmptyStrings()
|
||||
{
|
||||
// Arrange
|
||||
var line = new DiffLine
|
||||
{
|
||||
OldLineNumber = null,
|
||||
NewLineNumber = null,
|
||||
Text = "text",
|
||||
Type = DiffLineType.Unchanged
|
||||
};
|
||||
|
||||
// Act
|
||||
var sut = new DiffLineViewModel(line);
|
||||
|
||||
// Assert
|
||||
sut.OldLineNumber.ShouldBe("");
|
||||
sut.NewLineNumber.ShouldBe("");
|
||||
}
|
||||
}
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
using JdeScoping.ConfigManager.Core.Constants;
|
||||
using JdeScoping.ConfigManager.Ui.ViewModels.Dialogs;
|
||||
|
||||
namespace JdeScoping.ConfigManager.Ui.Tests.ViewModels.Dialogs;
|
||||
|
||||
public class NewStoreDialogViewModelTests
|
||||
{
|
||||
[Fact]
|
||||
public void StorePath_WhenEmpty_IsValidReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new NewStoreDialogViewModel
|
||||
{
|
||||
StorePath = "",
|
||||
KeyFilePath = "/path/to/key.key"
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
sut.IsValid.ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StorePath_WhenEmpty_ValidationErrorReturnsStorePathRequired()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new NewStoreDialogViewModel
|
||||
{
|
||||
StorePath = "",
|
||||
KeyFilePath = "/path/to/key.key"
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
sut.ValidationError.ShouldBe(SecureStoreStrings.StorePathRequired);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StorePath_WhenWhitespace_IsValidReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new NewStoreDialogViewModel
|
||||
{
|
||||
StorePath = " ",
|
||||
KeyFilePath = "/path/to/key.key"
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
sut.IsValid.ShouldBeFalse();
|
||||
sut.ValidationError.ShouldBe(SecureStoreStrings.StorePathRequired);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void KeyFilePath_WhenEmpty_IsValidReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new NewStoreDialogViewModel
|
||||
{
|
||||
StorePath = "/path/to/store.secure",
|
||||
KeyFilePath = ""
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
sut.IsValid.ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void KeyFilePath_WhenEmpty_ValidationErrorReturnsKeyFilePathRequired()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new NewStoreDialogViewModel
|
||||
{
|
||||
StorePath = "/path/to/store.secure",
|
||||
KeyFilePath = ""
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
sut.ValidationError.ShouldBe(SecureStoreStrings.KeyFilePathRequired);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void KeyFilePath_WhenProvided_IsValidReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new NewStoreDialogViewModel
|
||||
{
|
||||
StorePath = "/path/to/store.secure",
|
||||
KeyFilePath = "/path/to/key.key"
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
sut.IsValid.ShouldBeTrue();
|
||||
sut.ValidationError.ShouldBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StorePath_WhenChanged_RaisesPropertyChanged()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new NewStoreDialogViewModel();
|
||||
var propertyChangedRaised = false;
|
||||
sut.PropertyChanged += (s, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(NewStoreDialogViewModel.StorePath))
|
||||
propertyChangedRaised = true;
|
||||
};
|
||||
|
||||
// Act
|
||||
sut.StorePath = "/new/path";
|
||||
|
||||
// Assert
|
||||
propertyChangedRaised.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StorePath_WhenChanged_RaisesIsValidPropertyChanged()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new NewStoreDialogViewModel();
|
||||
var isValidPropertyChangedRaised = false;
|
||||
sut.PropertyChanged += (s, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(NewStoreDialogViewModel.IsValid))
|
||||
isValidPropertyChangedRaised = true;
|
||||
};
|
||||
|
||||
// Act
|
||||
sut.StorePath = "/new/path";
|
||||
|
||||
// Assert
|
||||
isValidPropertyChangedRaised.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StorePath_WhenChanged_RaisesValidationErrorPropertyChanged()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new NewStoreDialogViewModel();
|
||||
var validationErrorPropertyChangedRaised = false;
|
||||
sut.PropertyChanged += (s, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(NewStoreDialogViewModel.ValidationError))
|
||||
validationErrorPropertyChangedRaised = true;
|
||||
};
|
||||
|
||||
// Act
|
||||
sut.StorePath = "/new/path";
|
||||
|
||||
// Assert
|
||||
validationErrorPropertyChangedRaised.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void KeyFilePath_WhenChanged_RaisesPropertyChanged()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new NewStoreDialogViewModel();
|
||||
var propertyChangedRaised = false;
|
||||
sut.PropertyChanged += (s, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(NewStoreDialogViewModel.KeyFilePath))
|
||||
propertyChangedRaised = true;
|
||||
};
|
||||
|
||||
// Act
|
||||
sut.KeyFilePath = "/new/key/path";
|
||||
|
||||
// Assert
|
||||
propertyChangedRaised.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Commands_AreInitialized()
|
||||
{
|
||||
// Arrange & Act
|
||||
var sut = new NewStoreDialogViewModel();
|
||||
|
||||
// Assert
|
||||
sut.BrowseStorePathCommand.ShouldNotBeNull();
|
||||
sut.BrowseKeyFilePathCommand.ShouldNotBeNull();
|
||||
sut.GenerateKeyFileCommand.ShouldNotBeNull();
|
||||
}
|
||||
}
|
||||
+343
@@ -0,0 +1,343 @@
|
||||
using JdeScoping.ConfigManager.Core.Constants;
|
||||
using JdeScoping.ConfigManager.Ui.ViewModels.Dialogs;
|
||||
|
||||
namespace JdeScoping.ConfigManager.Ui.Tests.ViewModels.Dialogs;
|
||||
|
||||
public class SecretEditDialogViewModelTests
|
||||
{
|
||||
[Fact]
|
||||
public void DefaultConstructor_SetsIsNewSecretToTrue()
|
||||
{
|
||||
// Arrange & Act
|
||||
var sut = new SecretEditDialogViewModel();
|
||||
|
||||
// Assert
|
||||
sut.IsNewSecret.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DefaultConstructor_SetsKeyToEmpty()
|
||||
{
|
||||
// Arrange & Act
|
||||
var sut = new SecretEditDialogViewModel();
|
||||
|
||||
// Assert
|
||||
sut.Key.ShouldBeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DefaultConstructor_SetsValueToEmpty()
|
||||
{
|
||||
// Arrange & Act
|
||||
var sut = new SecretEditDialogViewModel();
|
||||
|
||||
// Assert
|
||||
sut.Value.ShouldBeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EditConstructor_SetsKeyFromParameter()
|
||||
{
|
||||
// Arrange & Act
|
||||
var sut = new SecretEditDialogViewModel("myKey", "myValue");
|
||||
|
||||
// Assert
|
||||
sut.Key.ShouldBe("myKey");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EditConstructor_SetsValueFromParameter()
|
||||
{
|
||||
// Arrange & Act
|
||||
var sut = new SecretEditDialogViewModel("myKey", "myValue");
|
||||
|
||||
// Assert
|
||||
sut.Value.ShouldBe("myValue");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EditConstructor_SetsIsNewSecretToFalse()
|
||||
{
|
||||
// Arrange & Act
|
||||
var sut = new SecretEditDialogViewModel("myKey", "myValue");
|
||||
|
||||
// Assert
|
||||
sut.IsNewSecret.ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Key_WhenEmpty_IsValidReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretEditDialogViewModel
|
||||
{
|
||||
Key = ""
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
sut.IsValid.ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Key_WhenEmpty_ValidationErrorReturnsKeyRequired()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretEditDialogViewModel
|
||||
{
|
||||
Key = ""
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
sut.ValidationError.ShouldBe(SecureStoreStrings.KeyRequired);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Key_WhenWhitespace_IsValidReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretEditDialogViewModel
|
||||
{
|
||||
Key = " "
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
sut.IsValid.ShouldBeFalse();
|
||||
sut.ValidationError.ShouldBe(SecureStoreStrings.KeyRequired);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Key_WhenProvided_IsValidReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretEditDialogViewModel
|
||||
{
|
||||
Key = "validKey"
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
sut.IsValid.ShouldBeTrue();
|
||||
sut.ValidationError.ShouldBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsKeyEditable_WhenIsNewSecretIsTrue_ReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretEditDialogViewModel();
|
||||
|
||||
// Act & Assert
|
||||
sut.IsKeyEditable.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsKeyEditable_WhenIsNewSecretIsFalse_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretEditDialogViewModel("existingKey", "existingValue");
|
||||
|
||||
// Act & Assert
|
||||
sut.IsKeyEditable.ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DialogTitle_WhenIsNewSecretIsTrue_ReturnsAddSecret()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretEditDialogViewModel();
|
||||
|
||||
// Act & Assert
|
||||
sut.DialogTitle.ShouldBe("Add Secret");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DialogTitle_WhenIsNewSecretIsFalse_ReturnsEditSecret()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretEditDialogViewModel("existingKey", "existingValue");
|
||||
|
||||
// Act & Assert
|
||||
sut.DialogTitle.ShouldBe("Edit Secret");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsNewSecret_WhenChanged_RaisesIsKeyEditablePropertyChanged()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretEditDialogViewModel();
|
||||
var isKeyEditablePropertyChangedRaised = false;
|
||||
sut.PropertyChanged += (s, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(SecretEditDialogViewModel.IsKeyEditable))
|
||||
isKeyEditablePropertyChangedRaised = true;
|
||||
};
|
||||
|
||||
// Act
|
||||
sut.IsNewSecret = false;
|
||||
|
||||
// Assert
|
||||
isKeyEditablePropertyChangedRaised.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsNewSecret_WhenChanged_RaisesDialogTitlePropertyChanged()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretEditDialogViewModel();
|
||||
var dialogTitlePropertyChangedRaised = false;
|
||||
sut.PropertyChanged += (s, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(SecretEditDialogViewModel.DialogTitle))
|
||||
dialogTitlePropertyChangedRaised = true;
|
||||
};
|
||||
|
||||
// Act
|
||||
sut.IsNewSecret = false;
|
||||
|
||||
// Assert
|
||||
dialogTitlePropertyChangedRaised.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Key_WhenChanged_RaisesPropertyChanged()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretEditDialogViewModel();
|
||||
var propertyChangedRaised = false;
|
||||
sut.PropertyChanged += (s, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(SecretEditDialogViewModel.Key))
|
||||
propertyChangedRaised = true;
|
||||
};
|
||||
|
||||
// Act
|
||||
sut.Key = "newKey";
|
||||
|
||||
// Assert
|
||||
propertyChangedRaised.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Key_WhenChanged_RaisesIsValidPropertyChanged()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretEditDialogViewModel();
|
||||
var isValidPropertyChangedRaised = false;
|
||||
sut.PropertyChanged += (s, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(SecretEditDialogViewModel.IsValid))
|
||||
isValidPropertyChangedRaised = true;
|
||||
};
|
||||
|
||||
// Act
|
||||
sut.Key = "newKey";
|
||||
|
||||
// Assert
|
||||
isValidPropertyChangedRaised.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Key_WhenChanged_RaisesValidationErrorPropertyChanged()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretEditDialogViewModel();
|
||||
var validationErrorPropertyChangedRaised = false;
|
||||
sut.PropertyChanged += (s, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(SecretEditDialogViewModel.ValidationError))
|
||||
validationErrorPropertyChangedRaised = true;
|
||||
};
|
||||
|
||||
// Act
|
||||
sut.Key = "newKey";
|
||||
|
||||
// Assert
|
||||
validationErrorPropertyChangedRaised.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Value_WhenChanged_RaisesPropertyChanged()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretEditDialogViewModel();
|
||||
var propertyChangedRaised = false;
|
||||
sut.PropertyChanged += (s, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(SecretEditDialogViewModel.Value))
|
||||
propertyChangedRaised = true;
|
||||
};
|
||||
|
||||
// Act
|
||||
sut.Value = "newValue";
|
||||
|
||||
// Assert
|
||||
propertyChangedRaised.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Value_CanBeEmpty_IsValidStillReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretEditDialogViewModel
|
||||
{
|
||||
Key = "validKey",
|
||||
Value = ""
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
sut.IsValid.ShouldBeTrue();
|
||||
sut.ValidationError.ShouldBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Value_CanBeNull_IsValidStillReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretEditDialogViewModel
|
||||
{
|
||||
Key = "validKey",
|
||||
Value = null!
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
sut.IsValid.ShouldBeTrue();
|
||||
sut.ValidationError.ShouldBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsNewSecret_WhenSetToSameValue_DoesNotRaisePropertyChanged()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretEditDialogViewModel();
|
||||
var propertyChangedCount = 0;
|
||||
sut.PropertyChanged += (s, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(SecretEditDialogViewModel.IsNewSecret))
|
||||
propertyChangedCount++;
|
||||
};
|
||||
|
||||
// Act
|
||||
sut.IsNewSecret = true; // Same value as default
|
||||
|
||||
// Assert
|
||||
propertyChangedCount.ShouldBe(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Key_WhenSetToSameValue_DoesNotRaisePropertyChanged()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new SecretEditDialogViewModel { Key = "testKey" };
|
||||
var propertyChangedCount = 0;
|
||||
sut.PropertyChanged += (s, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(SecretEditDialogViewModel.Key))
|
||||
propertyChangedCount++;
|
||||
};
|
||||
|
||||
// Act
|
||||
sut.Key = "testKey"; // Same value
|
||||
|
||||
// Assert
|
||||
propertyChangedCount.ShouldBe(0);
|
||||
}
|
||||
}
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
using JdeScoping.ConfigManager.Core.Constants;
|
||||
using JdeScoping.ConfigManager.Ui.ViewModels.Dialogs;
|
||||
|
||||
namespace JdeScoping.ConfigManager.Ui.Tests.ViewModels.Dialogs;
|
||||
|
||||
public class UnlockStoreDialogViewModelTests
|
||||
{
|
||||
[Fact]
|
||||
public void Constructor_SetsStorePathFromParameter()
|
||||
{
|
||||
// Arrange
|
||||
var storePath = "/path/to/store.secure";
|
||||
|
||||
// Act
|
||||
var sut = new UnlockStoreDialogViewModel(storePath);
|
||||
|
||||
// Assert
|
||||
sut.StorePath.ShouldBe(storePath);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_ThrowsOnNullStorePath()
|
||||
{
|
||||
// Act & Assert
|
||||
Should.Throw<ArgumentNullException>(() => new UnlockStoreDialogViewModel(null!));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StorePath_IsReadOnly()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new UnlockStoreDialogViewModel("/path/to/store.secure");
|
||||
|
||||
// Assert - StorePath property has no setter, verified by checking it returns what was passed
|
||||
sut.StorePath.ShouldBe("/path/to/store.secure");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void KeyFilePath_WhenEmpty_IsValidReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new UnlockStoreDialogViewModel("/path/to/store.secure")
|
||||
{
|
||||
KeyFilePath = ""
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
sut.IsValid.ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void KeyFilePath_WhenEmpty_ValidationErrorReturnsKeyFilePathRequired()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new UnlockStoreDialogViewModel("/path/to/store.secure")
|
||||
{
|
||||
KeyFilePath = ""
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
sut.ValidationError.ShouldBe(SecureStoreStrings.KeyFilePathRequired);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void KeyFilePath_WhenWhitespace_IsValidReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new UnlockStoreDialogViewModel("/path/to/store.secure")
|
||||
{
|
||||
KeyFilePath = " "
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
sut.IsValid.ShouldBeFalse();
|
||||
sut.ValidationError.ShouldBe(SecureStoreStrings.KeyFilePathRequired);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void KeyFilePath_WhenFileDoesNotExist_IsValidReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new UnlockStoreDialogViewModel("/path/to/store.secure")
|
||||
{
|
||||
KeyFilePath = "/nonexistent/path/to/key.key"
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
sut.IsValid.ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void KeyFilePath_WhenFileDoesNotExist_ValidationErrorReturnsKeyFileNotFound()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new UnlockStoreDialogViewModel("/path/to/store.secure")
|
||||
{
|
||||
KeyFilePath = "/nonexistent/path/to/key.key"
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
sut.ValidationError.ShouldBe(SecureStoreStrings.KeyFileNotFound);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void KeyFilePath_WhenChanged_RaisesPropertyChanged()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new UnlockStoreDialogViewModel("/path/to/store.secure");
|
||||
var propertyChangedRaised = false;
|
||||
sut.PropertyChanged += (s, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(UnlockStoreDialogViewModel.KeyFilePath))
|
||||
propertyChangedRaised = true;
|
||||
};
|
||||
|
||||
// Act
|
||||
sut.KeyFilePath = "/new/key/path";
|
||||
|
||||
// Assert
|
||||
propertyChangedRaised.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void KeyFilePath_WhenChanged_RaisesIsValidPropertyChanged()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new UnlockStoreDialogViewModel("/path/to/store.secure");
|
||||
var isValidPropertyChangedRaised = false;
|
||||
sut.PropertyChanged += (s, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(UnlockStoreDialogViewModel.IsValid))
|
||||
isValidPropertyChangedRaised = true;
|
||||
};
|
||||
|
||||
// Act
|
||||
sut.KeyFilePath = "/new/key/path";
|
||||
|
||||
// Assert
|
||||
isValidPropertyChangedRaised.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void KeyFilePath_WhenChanged_RaisesValidationErrorPropertyChanged()
|
||||
{
|
||||
// Arrange
|
||||
var sut = new UnlockStoreDialogViewModel("/path/to/store.secure");
|
||||
var validationErrorPropertyChangedRaised = false;
|
||||
sut.PropertyChanged += (s, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(UnlockStoreDialogViewModel.ValidationError))
|
||||
validationErrorPropertyChangedRaised = true;
|
||||
};
|
||||
|
||||
// Act
|
||||
sut.KeyFilePath = "/new/key/path";
|
||||
|
||||
// Assert
|
||||
validationErrorPropertyChangedRaised.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BrowseKeyFilePathCommand_IsInitialized()
|
||||
{
|
||||
// Arrange & Act
|
||||
var sut = new UnlockStoreDialogViewModel("/path/to/store.secure");
|
||||
|
||||
// Assert
|
||||
sut.BrowseKeyFilePathCommand.ShouldNotBeNull();
|
||||
}
|
||||
}
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
using JdeScoping.ConfigManager.Core.Services;
|
||||
using JdeScoping.ConfigManager.Ui.ViewModels.Dialogs;
|
||||
|
||||
namespace JdeScoping.ConfigManager.Ui.Tests.ViewModels.Dialogs;
|
||||
|
||||
public class ValidationResultsDialogViewModelTests
|
||||
{
|
||||
[Fact]
|
||||
public void Constructor_WithEmptyResults_HasNoItems()
|
||||
{
|
||||
// Arrange
|
||||
var appSettingsResult = new ValidationResult();
|
||||
var pipelinesResult = new ValidationResult();
|
||||
|
||||
// Act
|
||||
var sut = new ValidationResultsDialogViewModel(appSettingsResult, pipelinesResult);
|
||||
|
||||
// Assert
|
||||
sut.Items.Count.ShouldBe(0);
|
||||
sut.ErrorCount.ShouldBe(0);
|
||||
sut.WarningCount.ShouldBe(0);
|
||||
sut.IsValid.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_WithErrors_PopulatesItemsCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
var appSettingsResult = new ValidationResult();
|
||||
appSettingsResult.AddError("Missing connection string");
|
||||
appSettingsResult.AddError("Invalid timeout value");
|
||||
var pipelinesResult = new ValidationResult();
|
||||
|
||||
// Act
|
||||
var sut = new ValidationResultsDialogViewModel(appSettingsResult, pipelinesResult);
|
||||
|
||||
// Assert
|
||||
sut.Items.Count.ShouldBe(2);
|
||||
sut.ErrorCount.ShouldBe(2);
|
||||
sut.WarningCount.ShouldBe(0);
|
||||
sut.IsValid.ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_WithWarnings_PopulatesItemsCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
var appSettingsResult = new ValidationResult();
|
||||
appSettingsResult.AddWarning("Deprecated setting used");
|
||||
var pipelinesResult = new ValidationResult();
|
||||
pipelinesResult.AddWarning("Pipeline has no transformers");
|
||||
|
||||
// Act
|
||||
var sut = new ValidationResultsDialogViewModel(appSettingsResult, pipelinesResult);
|
||||
|
||||
// Assert
|
||||
sut.Items.Count.ShouldBe(2);
|
||||
sut.ErrorCount.ShouldBe(0);
|
||||
sut.WarningCount.ShouldBe(2);
|
||||
sut.IsValid.ShouldBeFalse(); // Both errors and warnings make it invalid
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_WithMixedResults_PopulatesAllItems()
|
||||
{
|
||||
// Arrange
|
||||
var appSettingsResult = new ValidationResult();
|
||||
appSettingsResult.AddError("Error in appsettings");
|
||||
appSettingsResult.AddWarning("Warning in appsettings");
|
||||
var pipelinesResult = new ValidationResult();
|
||||
pipelinesResult.AddError("Error in pipelines");
|
||||
pipelinesResult.AddWarning("Warning in pipelines");
|
||||
|
||||
// Act
|
||||
var sut = new ValidationResultsDialogViewModel(appSettingsResult, pipelinesResult);
|
||||
|
||||
// Assert
|
||||
sut.Items.Count.ShouldBe(4);
|
||||
sut.ErrorCount.ShouldBe(2);
|
||||
sut.WarningCount.ShouldBe(2);
|
||||
sut.IsValid.ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_SetsCorrectSourceOnItems()
|
||||
{
|
||||
// Arrange
|
||||
var appSettingsResult = new ValidationResult();
|
||||
appSettingsResult.AddError("App error");
|
||||
var pipelinesResult = new ValidationResult();
|
||||
pipelinesResult.AddError("Pipeline error");
|
||||
|
||||
// Act
|
||||
var sut = new ValidationResultsDialogViewModel(appSettingsResult, pipelinesResult);
|
||||
|
||||
// Assert
|
||||
sut.Items.ShouldContain(i => i.Source == "appsettings.json" && i.Message == "App error");
|
||||
sut.Items.ShouldContain(i => i.Source == "pipelines.json" && i.Message == "Pipeline error");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CloseCommand_InvokesRequestClose()
|
||||
{
|
||||
// Arrange
|
||||
var appSettingsResult = new ValidationResult();
|
||||
var pipelinesResult = new ValidationResult();
|
||||
var sut = new ValidationResultsDialogViewModel(appSettingsResult, pipelinesResult);
|
||||
var closeInvoked = false;
|
||||
sut.RequestClose = () => closeInvoked = true;
|
||||
|
||||
// Act
|
||||
sut.CloseCommand.Execute(null);
|
||||
|
||||
// Assert
|
||||
closeInvoked.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CloseCommand_DoesNotThrow_WhenRequestCloseIsNull()
|
||||
{
|
||||
// Arrange
|
||||
var appSettingsResult = new ValidationResult();
|
||||
var pipelinesResult = new ValidationResult();
|
||||
var sut = new ValidationResultsDialogViewModel(appSettingsResult, pipelinesResult);
|
||||
sut.RequestClose = null;
|
||||
|
||||
// Act & Assert - Should not throw
|
||||
Should.NotThrow(() => sut.CloseCommand.Execute(null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_ThrowsOnNullAppSettingsResult()
|
||||
{
|
||||
// Arrange
|
||||
var pipelinesResult = new ValidationResult();
|
||||
|
||||
// Act & Assert
|
||||
Should.Throw<ArgumentNullException>(() =>
|
||||
new ValidationResultsDialogViewModel(null!, pipelinesResult));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_ThrowsOnNullPipelinesResult()
|
||||
{
|
||||
// Arrange
|
||||
var appSettingsResult = new ValidationResult();
|
||||
|
||||
// Act & Assert
|
||||
Should.Throw<ArgumentNullException>(() =>
|
||||
new ValidationResultsDialogViewModel(appSettingsResult, null!));
|
||||
}
|
||||
}
|
||||
|
||||
public class ValidationItemViewModelTests
|
||||
{
|
||||
[Fact]
|
||||
public void Constructor_SetsPropertiesCorrectly()
|
||||
{
|
||||
// Act
|
||||
var sut = new ValidationItemViewModel("Test message", "test.json", ValidationItemType.Error);
|
||||
|
||||
// Assert
|
||||
sut.Message.ShouldBe("Test message");
|
||||
sut.Source.ShouldBe("test.json");
|
||||
sut.Type.ShouldBe(ValidationItemType.Error);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_ErrorType_SetsErrorStyling()
|
||||
{
|
||||
// Act
|
||||
var sut = new ValidationItemViewModel("Error", "test.json", ValidationItemType.Error);
|
||||
|
||||
// Assert
|
||||
sut.Icon.ShouldBe("\u2717"); // X mark
|
||||
sut.IconColor.ShouldBe("#FF6B6B");
|
||||
sut.Background.ShouldBe("#1AFF6B6B");
|
||||
sut.BorderColor.ShouldBe("#FF6B6B");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_WarningType_SetsWarningStyling()
|
||||
{
|
||||
// Act
|
||||
var sut = new ValidationItemViewModel("Warning", "test.json", ValidationItemType.Warning);
|
||||
|
||||
// Assert
|
||||
sut.Icon.ShouldBe("\u26A0"); // Warning sign
|
||||
sut.IconColor.ShouldBe("#FFB84D");
|
||||
sut.Background.ShouldBe("#1AFFB84D");
|
||||
sut.BorderColor.ShouldBe("#FFB84D");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user