From eaaa6e2bb60b11cf56a5c2450565d120384b322a Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Mon, 19 Jan 2026 15:00:12 +0100 Subject: [PATCH 1/2] Fix ConfigurationValidator incorrectly validating non-existent CommerceConfiguration (#579) * Initial plan * Fix ConfigurationValidator to properly check if CommerceConfiguration exists and add tests Co-authored-by: petrinecp <5637849+petrinecp@users.noreply.github.com> * Fix code formatting to pass dotnet format verification Co-authored-by: petrinecp <5637849+petrinecp@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: petrinecp <5637849+petrinecp@users.noreply.github.com> --- Migration.Tool.CLI/ConfigurationValidator.cs | 2 +- .../ConfigurationValidatorTests.cs | 73 +++++++++++++++++++ .../Migration.Tool.Tests.csproj | 1 + 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 Migration.Tool.Tests/ConfigurationValidatorTests.cs diff --git a/Migration.Tool.CLI/ConfigurationValidator.cs b/Migration.Tool.CLI/ConfigurationValidator.cs index 2e8a9a0b..56287c51 100644 --- a/Migration.Tool.CLI/ConfigurationValidator.cs +++ b/Migration.Tool.CLI/ConfigurationValidator.cs @@ -161,7 +161,7 @@ public static IEnumerable GetValidationErrors(IConfigurationR #region Commerce configuration validation var commerceConfiguration = settings?.GetSection(ConfigurationNames.CommerceConfiguration); - if (commerceConfiguration is not null) + if (commerceConfiguration?.Exists() == true) { var commerceSiteNames = commerceConfiguration.GetSection(ConfigurationNames.CommerceSiteNames).Get?>(); if (commerceSiteNames is null || commerceSiteNames.Count == 0) diff --git a/Migration.Tool.Tests/ConfigurationValidatorTests.cs b/Migration.Tool.Tests/ConfigurationValidatorTests.cs new file mode 100644 index 00000000..9d501f20 --- /dev/null +++ b/Migration.Tool.Tests/ConfigurationValidatorTests.cs @@ -0,0 +1,73 @@ +using Microsoft.Extensions.Configuration; +using Migration.Tool.CLI; + +namespace Migration.Tool.Tests; + +public class ConfigurationValidatorTests +{ + [Fact] + public void GetValidationErrors_WhenCommerceConfigurationSectionDoesNotExist_ShouldNotReturnValidationErrors() + { + // Arrange - Create configuration without CommerceConfiguration section + var configuration = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + ["Settings:KxConnectionString"] = "Server=localhost;Database=Kentico;", + ["Settings:XbyKDirPath"] = "C:\\XbyK", + ["Settings:XbyKApiSettings:ConnectionStrings:CMSConnectionString"] = "Server=localhost;Database=XbyK;" + }) + .Build(); + + // Act + var errors = ConfigurationValidator.GetValidationErrors(configuration).ToList(); + + // Assert - Should not contain CommerceConfiguration validation error + Assert.DoesNotContain(errors, e => e.Message.Contains("CommerceConfiguration")); + } + + [Fact] + public void GetValidationErrors_WhenCommerceConfigurationExistsWithEmptySiteNames_ShouldReturnValidationError() + { + // Arrange - Create configuration with CommerceConfiguration section containing empty site name + var configuration = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + ["Settings:KxConnectionString"] = "Server=localhost;Database=Kentico;", + ["Settings:XbyKDirPath"] = "C:\\XbyK", + ["Settings:XbyKApiSettings:ConnectionStrings:CMSConnectionString"] = "Server=localhost;Database=XbyK;", + ["Settings:CommerceConfiguration:CommerceSiteNames:0"] = "" // Empty value + }) + .Build(); + + // Act + var errors = ConfigurationValidator.GetValidationErrors(configuration).ToList(); + + // Assert - Should contain validation error for empty site names + Assert.Contains(errors, e => e.Message.Contains("CommerceConfiguration:CommerceSiteNames") && + e.Message.Contains("cannot contain empty or whitespace values")); + } + + [Fact] + public void GetValidationErrors_WhenCommerceConfigurationExistsWithValidSiteNames_ShouldNotReturnCommerceValidationErrors() + { + // Arrange - Create configuration with valid CommerceConfiguration + var configuration = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + ["Settings:KxConnectionString"] = "Server=localhost;Database=Kentico;", + ["Settings:XbyKDirPath"] = "C:\\XbyK", + ["Settings:XbyKApiSettings:ConnectionStrings:CMSConnectionString"] = "Server=localhost;Database=XbyK;", + ["Settings:CommerceConfiguration:CommerceSiteNames:0"] = "MySite" + }) + .Build(); + + // Act + var errors = ConfigurationValidator.GetValidationErrors(configuration).ToList(); + + // Assert - Should not contain CommerceConfiguration validation errors + Assert.DoesNotContain(errors, e => e.Message.Contains("CommerceConfiguration:CommerceSiteNames") && + e.Message.Contains("must contain at least one site name")); + Assert.DoesNotContain(errors, e => e.Message.Contains("CommerceConfiguration:CommerceSiteNames") && + e.Message.Contains("cannot contain empty or whitespace values")); + } +} diff --git a/Migration.Tool.Tests/Migration.Tool.Tests.csproj b/Migration.Tool.Tests/Migration.Tool.Tests.csproj index 93aab141..5ddb0cef 100644 --- a/Migration.Tool.Tests/Migration.Tool.Tests.csproj +++ b/Migration.Tool.Tests/Migration.Tool.Tests.csproj @@ -19,6 +19,7 @@ + From f9d5ee46e7a5ef470b3b3d38aad26d7353392e68 Mon Sep 17 00:00:00 2001 From: Peter Petrinec Date: Thu, 22 Jan 2026 13:29:11 +0100 Subject: [PATCH 2/2] Adjust version matrix --- README.md | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 61ea2069..3f7b2780 100644 --- a/README.md +++ b/README.md @@ -129,27 +129,25 @@ To understand when and how to implement customizations: View all [project releases](https://github.com/Kentico/xperience-by-kentico-kentico-migration-tool/releases/). | Xperience Version | Library Version | -| ----------------- | --------------- | -| 31.0.0 | 4.1.0 | -| 31.0.0 | 4.0.0 | -| 30.12.0 | 3.21.0 | -| 30.12.0 | 3.20.0 | -| 30.11.0 | 3.18.0 | -| 30.10.1 | 3.16.0 | -| 30.8.0 | 3.12.0 | -| 30.6.0 | 3.8.0 | -| 30.5.1 | 3.6.0 | -| 30.4.0 | 3.4.0 | -| 30.3.1 | 3.3.0 | -| 30.2.0 | 3.0.0 | -| 30.1.1 | 2.3.0 | -| 30.0.0 | 2.0.0 | -| 29.7.0 | 1.6.0 | -| 29.6.0 | 1.4.0 | -| 29.5.2 | 1.3.0 | -| 29.3.3 | 1.2.0 | -| 29.2.0 | 1.1.0 | -| 29.1.0 | 1.0.0 | +| ------------------| ----------------| +| >= 31.0.0 | >= 4.0.0 | +| >= 30.12.0 | >= 3.20.0 | +| >= 30.11.0 | >= 3.18.0 | +| >= 30.10.1 | >= 3.16.0 | +| >= 30.8.0 | >= 3.12.0 | +| >= 30.6.0 | >= 3.8.0 | +| >= 30.5.1 | >= 3.6.0 | +| >= 30.4.0 | >= 3.4.0 | +| >= 30.3.1 | >= 3.3.0 | +| >= 30.2.0 | >= 3.0.0 | +| >= 30.1.1 | >= 2.3.0 | +| >= 30.0.0 | >= 2.0.0 | +| >= 29.7.0 | >= 1.6.0 | +| >= 29.6.0 | >= 1.4.0 | +| >= 29.5.2 | >= 1.3.0 | +| >= 29.3.3 | >= 1.2.0 | +| >= 29.2.0 | >= 1.1.0 | +| >= 29.1.0 | >= 1.0.0 | ## Dependencies