using JdeScoping.ConfigManager.Core.Models; using JdeScoping.ConfigManager.Core.Services; using JdeScoping.DataSync.Configuration; namespace JdeScoping.ConfigManager.Core.Tests.Services; public class ValidationServiceTests { private readonly ValidationService _sut; public ValidationServiceTests() { _sut = new ValidationService(); } [Fact] public void ValidateAppSettings_WithValidConfig_ReturnsNoErrors() { // Arrange var config = new ConfigModel { DataSync = new DataSyncSection { MaxDegreeOfParallelism = 4 } }; // Act var result = _sut.ValidateAppSettings(config); // Assert result.IsValid.ShouldBeTrue(); result.Errors.ShouldBeEmpty(); } [Fact] public void ValidateAppSettings_WithInvalidParallelism_ReturnsError() { // Arrange var config = new ConfigModel { DataSync = new DataSyncSection { MaxDegreeOfParallelism = 0 } }; // Act var result = _sut.ValidateAppSettings(config); // Assert result.IsValid.ShouldBeFalse(); result.Errors.ShouldContain(e => e.Contains("MaxDegreeOfParallelism")); } [Fact] public void ValidatePipelines_WithEmptyName_ReturnsError() { // Arrange var pipelines = new Dictionary { [""] = new EtlPipelineConfig() }; // Act var result = _sut.ValidatePipelines(pipelines); // Assert result.IsValid.ShouldBeFalse(); } [Fact] public void ValidatePipelines_WithInvalidConnection_ReturnsError() { // Arrange var pipelines = new Dictionary { ["Test"] = new EtlPipelineConfig { Source = new SourceElement { Connection = "invalid" } } }; // Act var result = _sut.ValidatePipelines(pipelines); // Assert result.IsValid.ShouldBeFalse(); result.Errors.ShouldContain(e => e.Contains("Connection")); } [Fact] public void ValidatePipeline_WithValidConfig_ReturnsNoErrors() { // Arrange var pipeline = new EtlPipelineConfig { Name = "Test", IsEnabled = true, Source = new SourceElement { Connection = "jde", Query = "SELECT * FROM Test" }, Destination = new DestinationElement { Table = "TestTable", MatchColumns = ["Id"] }, HourlySyncIntervalMinutes = 60 }; // Act var result = _sut.ValidatePipeline(pipeline, "Test"); // Assert result.IsValid.ShouldBeTrue(); result.Errors.ShouldBeEmpty(); } [Fact] public void ValidatePipeline_WithMissingQuery_ReturnsError() { // Arrange var pipeline = new EtlPipelineConfig { Source = new SourceElement { Connection = "jde", Query = "" }, Destination = new DestinationElement { Table = "TestTable" }, IsManualOnly = true }; // Act var result = _sut.ValidatePipeline(pipeline, "Test"); // Assert result.IsValid.ShouldBeFalse(); result.Errors.ShouldContain(e => e.Contains("Query")); } [Fact] public void ValidatePipeline_WithNoScheduleAndNotManual_ReturnsWarning() { // Arrange var pipeline = new EtlPipelineConfig { Source = new SourceElement { Connection = "jde", Query = "SELECT 1" }, Destination = new DestinationElement { Table = "TestTable", MatchColumns = ["Id"] }, IsManualOnly = false // No schedules and not manual-only }; // Act var result = _sut.ValidatePipeline(pipeline, "Test"); // Assert result.Warnings.ShouldContain(w => w.Contains("No sync schedule")); } [Fact] public void ValidatePipeline_ManualOnly_DoesNotRequireSchedule() { // Arrange var pipeline = new EtlPipelineConfig { Source = new SourceElement { Connection = "jde", Query = "SELECT 1" }, Destination = new DestinationElement { Table = "TestTable", MatchColumns = ["Id"] }, IsManualOnly = true }; // Act var result = _sut.ValidatePipeline(pipeline, "Test"); // Assert result.Warnings.ShouldNotContain(w => w.Contains("No sync schedule")); } [Fact] public void ValidatePipeline_WithIntervalBelowMinimum_ReturnsError() { // Arrange var pipeline = new EtlPipelineConfig { Source = new SourceElement { Connection = "jde", Query = "SELECT 1" }, Destination = new DestinationElement { Table = "TestTable" }, HourlySyncIntervalMinutes = 5 // Below minimum of 15 }; // Act var result = _sut.ValidatePipeline(pipeline, "Test"); // Assert result.IsValid.ShouldBeFalse(); result.Errors.ShouldContain(e => e.Contains("Hourly sync interval")); } [Fact] public void ValidatePipeline_WithNoMatchColumns_ReturnsWarning() { // Arrange var pipeline = new EtlPipelineConfig { Source = new SourceElement { Connection = "jde", Query = "SELECT 1" }, Destination = new DestinationElement { Table = "TestTable", MatchColumns = [] }, IsManualOnly = true }; // Act var result = _sut.ValidatePipeline(pipeline, "Test"); // Assert result.Warnings.ShouldContain(w => w.Contains("No MatchColumns")); } }