using JdeScoping.ConfigManager.ViewModels.PipelineSteps; using JdeScoping.DataSync.Configuration; using System.Text.Json; namespace JdeScoping.ConfigManager.Tests.ViewModels; public class RegexTransformerViewModelTests { private static readonly JsonSerializerOptions JsonOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; private static TransformElement CreateElement(object config) { var json = JsonSerializer.Serialize(config, JsonOptions); using var doc = JsonDocument.Parse(json); return new TransformElement { TransformType = "Regex", Config = doc.RootElement.Clone() }; } [Fact] public void Constructor_FromElement_LoadsAllProperties() { // Arrange var element = CreateElement(new { columnName = "BatchID", pattern = "^IIS_", replacement = "", ignoreCase = true, nonMatchBehavior = "ReturnEmpty" }); // Act var vm = new RegexTransformerViewModel(element, () => { }); // Assert Assert.Equal("BatchID", vm.ColumnName); Assert.Equal("^IIS_", vm.Pattern); Assert.Equal("", vm.Replacement); Assert.True(vm.IsFindReplaceMode); Assert.True(vm.IgnoreCase); Assert.Equal(NonMatchBehavior.ReturnEmpty, vm.NonMatchBehavior); } [Fact] public void Constructor_FromElement_MatchExtractMode_WhenReplacementNull() { // Arrange var element = CreateElement(new { columnName = "Code", pattern = @"(\d+)" }); // Act var vm = new RegexTransformerViewModel(element, () => { }); // Assert Assert.False(vm.IsFindReplaceMode); Assert.True(vm.IsMatchExtractMode); } [Fact] public void ToModel_SerializesCorrectly_FindReplaceMode() { // Arrange var vm = new RegexTransformerViewModel(() => { }) { ColumnName = "BatchID", Pattern = "^IIS_", Replacement = "", IsFindReplaceMode = true, IgnoreCase = true, NonMatchBehavior = NonMatchBehavior.KeepOriginal }; // Act var element = vm.ToModel(); // Assert Assert.Equal("Regex", element.TransformType); Assert.True(element.Config.HasValue); // Parse the config to verify var config = element.Config!.Value; Assert.Equal("BatchID", config.GetProperty("columnName").GetString()); Assert.Equal("^IIS_", config.GetProperty("pattern").GetString()); Assert.Equal("", config.GetProperty("replacement").GetString()); Assert.True(config.GetProperty("ignoreCase").GetBoolean()); } [Fact] public void ToModel_SerializesCorrectly_MatchExtractMode() { // Arrange var vm = new RegexTransformerViewModel(() => { }) { ColumnName = "Code", Pattern = @"(\d+)", IsFindReplaceMode = false }; // Act var element = vm.ToModel(); // Assert Assert.True(element.Config.HasValue); var config = element.Config!.Value; // replacement should be null in Match & Extract mode Assert.True(config.TryGetProperty("replacement", out var replacement)); Assert.Equal(JsonValueKind.Null, replacement.ValueKind); } [Fact] public void TestPatternCommand_ValidPattern_ShowsResult() { // Arrange var vm = new RegexTransformerViewModel(() => { }) { Pattern = "^IIS_", Replacement = "", IsFindReplaceMode = true, TestInput = "IIS_12345" }; // Act vm.TestPatternCommand.Execute(null); // Assert Assert.True(vm.HasTestResult); Assert.False(vm.HasTestError); Assert.Equal("12345", vm.TestResultValue); Assert.Equal("Output", vm.TestResultLabel); Assert.Equal("✓", vm.TestResultIcon); } [Fact] public void TestPatternCommand_InvalidPattern_ShowsError() { // Arrange var vm = new RegexTransformerViewModel(() => { }) { Pattern = "[invalid(regex", Replacement = "", TestInput = "test" }; // Act vm.TestPatternCommand.Execute(null); // Assert Assert.False(vm.HasTestResult); Assert.True(vm.HasTestError); Assert.NotEmpty(vm.TestErrorMessage); } [Fact] public void TestPatternCommand_MatchExtract_NoMatch_ShowsNonMatchBehavior() { // Arrange var vm = new RegexTransformerViewModel(() => { }) { Pattern = @"(\d+)", IsFindReplaceMode = false, NonMatchBehavior = NonMatchBehavior.ReturnNull, TestInput = "NoNumbers" }; // Act vm.TestPatternCommand.Execute(null); // Assert Assert.True(vm.HasTestResult); Assert.Equal("No Match", vm.TestResultLabel); Assert.Equal("(null)", vm.TestResultValue); } [Fact] public void ModeSwitch_UpdatesPatternHelpText() { // Arrange var vm = new RegexTransformerViewModel(() => { }) { IsFindReplaceMode = true }; var findReplaceHelp = vm.PatternHelpText; // Act vm.IsFindReplaceMode = false; var matchExtractHelp = vm.PatternHelpText; // Assert Assert.NotEqual(findReplaceHelp, matchExtractHelp); Assert.Contains("capture group", matchExtractHelp, StringComparison.OrdinalIgnoreCase); } [Fact] public void Summary_ShowsColumnAndMode() { // Arrange & Act var vm = new RegexTransformerViewModel(() => { }) { ColumnName = "BatchID", IsFindReplaceMode = true }; // Assert Assert.Contains("BatchID", vm.Summary); Assert.Contains("Replace", vm.Summary); } [Fact] public void PropertyChange_NotifiesChanged() { // Arrange var changedCalled = false; var vm = new RegexTransformerViewModel(() => changedCalled = true); // Act vm.ColumnName = "NewColumn"; // Assert Assert.True(changedCalled); } }