test(configmanager): expand unit test coverage to 451 tests
Add comprehensive tests for services (ConnectionTestService, RuntimeConfigValidation), ViewModels (PipelineEditor, dialogs, transformers), and Avalonia headless UI tests for views and forms.
This commit is contained in:
+241
@@ -0,0 +1,241 @@
|
||||
using JdeScoping.ConfigManager.Services;
|
||||
using JdeScoping.ConfigManager.ViewModels.Dialogs;
|
||||
|
||||
namespace JdeScoping.ConfigManager.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("");
|
||||
}
|
||||
}
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
using JdeScoping.ConfigManager.Services;
|
||||
using JdeScoping.ConfigManager.ViewModels.Dialogs;
|
||||
|
||||
namespace JdeScoping.ConfigManager.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