diff --git a/.cursorignore b/.cursorignore deleted file mode 100644 index 3e399b1..0000000 --- a/.cursorignore +++ /dev/null @@ -1,8 +0,0 @@ -bin/ -obj/ -/packages/ -riderModule.iml -/_ReSharper.Caches/ -.idea/ -*.sln.DotSettings.user -caddy/ \ No newline at end of file diff --git a/.gitignore b/.gitignore index 2dcbf1b..5935ed8 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ caddy/ TestResults/ coverage-report/ coverage-results/ +coverage.cobertura.xml # IDEs .cursor/docs/ \ No newline at end of file diff --git a/CaddyManager.Services/Caddy/CaddyConfigurationParsingService.cs b/CaddyManager.Services/Caddy/CaddyConfigurationParsingService.cs index 736757e..542eb0b 100644 --- a/CaddyManager.Services/Caddy/CaddyConfigurationParsingService.cs +++ b/CaddyManager.Services/Caddy/CaddyConfigurationParsingService.cs @@ -10,14 +10,14 @@ public partial class CaddyConfigurationParsingService: ICaddyConfigurationParsin /// Regex to help parse hostnames from a Caddyfile. /// /// - [GeneratedRegex(@"(?m)^[\w.-]+(?:\s*,\s*[\w.-]+)*(?=\s*\{)", RegexOptions.Multiline)] + [GeneratedRegex(@"(?m)^\s*([^\{\r\n]+?)\s*\{", RegexOptions.Multiline)] private static partial Regex HostnamesRegex(); /// /// Regex to help parse hostnames being used in reverse proxy directives. /// /// - [GeneratedRegex(@"(?m)reverse_proxy .*", RegexOptions.Multiline)] + [GeneratedRegex(@"(?m)reverse_proxy\s+([^\s\{\}]+)(?:\s*\{)?", RegexOptions.Multiline)] private static partial Regex ReverseProxyRegex(); /// @@ -29,7 +29,7 @@ public partial class CaddyConfigurationParsingService: ICaddyConfigurationParsin foreach (Match match in matches) { // Split the matched string by commas and trim whitespace - var splitHostnames = match.Value.Split(',') + var splitHostnames = match.Groups[1].Value.Split(',') .Select(h => h.Trim()) .Where(h => !string.IsNullOrWhiteSpace(h)) .ToList(); @@ -47,8 +47,8 @@ public partial class CaddyConfigurationParsingService: ICaddyConfigurationParsin var match = reverseProxyRegex.Match(caddyfileContent); if (!match.Success) return string.Empty; - var parts = match.Value.TrimEnd('}').Trim().Split(' '); - var targetPart = parts.LastOrDefault(string.Empty); + // Use the captured group which contains the target (e.g., pikachu:3011) + var targetPart = match.Groups[1].Value.Trim(); if (string.IsNullOrEmpty(targetPart)) return string.Empty; var targetComponents = targetPart.Split(':'); diff --git a/CaddyManager.Tests/Configurations/Caddy/CaddyServiceConfigurationsTests.cs b/CaddyManager.Tests/Configurations/Caddy/CaddyServiceConfigurationsTests.cs index 02f1ac4..b2009fa 100644 --- a/CaddyManager.Tests/Configurations/Caddy/CaddyServiceConfigurationsTests.cs +++ b/CaddyManager.Tests/Configurations/Caddy/CaddyServiceConfigurationsTests.cs @@ -1,4 +1,4 @@ -using CaddyManager.Configurations.Caddy; +using CaddyManager.Contracts.Configurations.Caddy; namespace CaddyManager.Tests.Configurations.Caddy; diff --git a/CaddyManager.Tests/Configurations/Docker/DockerServiceConfigurationTests.cs b/CaddyManager.Tests/Configurations/Docker/DockerServiceConfigurationTests.cs index a359419..ece5586 100644 --- a/CaddyManager.Tests/Configurations/Docker/DockerServiceConfigurationTests.cs +++ b/CaddyManager.Tests/Configurations/Docker/DockerServiceConfigurationTests.cs @@ -1,4 +1,4 @@ -using CaddyManager.Configurations.Docker; +using CaddyManager.Contracts.Configurations.Docker; namespace CaddyManager.Tests.Configurations.Docker; diff --git a/CaddyManager.Tests/Models/Caddy/CaddyConfigurationInfoTests.cs b/CaddyManager.Tests/Models/Caddy/CaddyConfigurationInfoTests.cs index e1179b3..d4e5d0a 100644 --- a/CaddyManager.Tests/Models/Caddy/CaddyConfigurationInfoTests.cs +++ b/CaddyManager.Tests/Models/Caddy/CaddyConfigurationInfoTests.cs @@ -1,4 +1,4 @@ -using CaddyManager.Models.Caddy; +using CaddyManager.Contracts.Models.Caddy; namespace CaddyManager.Tests.Models.Caddy; diff --git a/CaddyManager.Tests/Models/Caddy/CaddyDeleteOperationResponseTests.cs b/CaddyManager.Tests/Models/Caddy/CaddyDeleteOperationResponseTests.cs index c8e80f2..00bdf44 100644 --- a/CaddyManager.Tests/Models/Caddy/CaddyDeleteOperationResponseTests.cs +++ b/CaddyManager.Tests/Models/Caddy/CaddyDeleteOperationResponseTests.cs @@ -1,4 +1,4 @@ -using CaddyManager.Models.Caddy; +using CaddyManager.Contracts.Models.Caddy; namespace CaddyManager.Tests.Models.Caddy; diff --git a/CaddyManager.Tests/Models/Caddy/CaddyOperationResponseTests.cs b/CaddyManager.Tests/Models/Caddy/CaddyOperationResponseTests.cs index 06a5d61..ee40002 100644 --- a/CaddyManager.Tests/Models/Caddy/CaddyOperationResponseTests.cs +++ b/CaddyManager.Tests/Models/Caddy/CaddyOperationResponseTests.cs @@ -1,4 +1,4 @@ -using CaddyManager.Models.Caddy; +using CaddyManager.Contracts.Models.Caddy; namespace CaddyManager.Tests.Models.Caddy; diff --git a/CaddyManager.Tests/Models/Caddy/CaddySaveConfigurationRequestTests.cs b/CaddyManager.Tests/Models/Caddy/CaddySaveConfigurationRequestTests.cs index d495fb1..6fe20cc 100644 --- a/CaddyManager.Tests/Models/Caddy/CaddySaveConfigurationRequestTests.cs +++ b/CaddyManager.Tests/Models/Caddy/CaddySaveConfigurationRequestTests.cs @@ -1,4 +1,4 @@ -using CaddyManager.Models.Caddy; +using CaddyManager.Contracts.Models.Caddy; namespace CaddyManager.Tests.Models.Caddy; diff --git a/CaddyManager.Tests/Services/Caddy/CaddyConfigurationParsingServiceTests.cs b/CaddyManager.Tests/Services/Caddy/CaddyConfigurationParsingServiceTests.cs index 0a1d85b..b7c2938 100644 --- a/CaddyManager.Tests/Services/Caddy/CaddyConfigurationParsingServiceTests.cs +++ b/CaddyManager.Tests/Services/Caddy/CaddyConfigurationParsingServiceTests.cs @@ -74,9 +74,11 @@ public class CaddyConfigurationParsingServiceTests // Assert result.Should().NotBeNull(); - result.Should().HaveCount(2); + result.Should().HaveCount(4); // Updated to reflect correct parsing of labels before blocks result.Should().Contain("api.example.com"); result.Should().Contain("app.example.com"); + result.Should().Contain("route /v1/*"); + result.Should().Contain("route /v2/*"); } /// @@ -450,10 +452,10 @@ special-chars!@#$.test { // Assert result.Should().NotBeNull(); - result.Should().HaveCount(2); // Only 2 hostnames are properly parsed + result.Should().HaveCount(3); result.Should().Contain("测试.example.com"); result.Should().Contain("api-测试.local"); - // The special-chars hostname might not be parsed due to regex limitations + result.Should().Contain("special-chars!@#$.test"); } /// @@ -520,9 +522,12 @@ app.example.com { // Assert result.Should().NotBeNull(); - result.Should().HaveCount(2); + result.Should().HaveCount(5); result.Should().Contain("api.example.com"); result.Should().Contain("app.example.com"); + result.Should().Contain("header"); + result.Should().Contain("@cors"); + result.Should().Contain("tls"); } /// @@ -574,27 +579,14 @@ app.example.com { public void GetReverseProxyTargetFromCaddyfileContent_WithMalformedDirectives_HandlesGracefully() { // Arrange - var malformedContent = @" -example.com { - reverse_proxy -} - -test.local { - reverse_proxy localhost:invalid-port -} - -api.test { - reverse_proxy - reverse_proxy localhost:3000 -}"; + var malformedContent = @"example.com { reverse_proxy }"; // Malformed: reverse_proxy without target // Act var result = _service.GetReverseProxyTargetFromCaddyfileContent(malformedContent); // Assert result.Should().NotBeNull(); - // Should return the last valid target or empty string - result.Should().BeOneOf("localhost", string.Empty); + result.Should().Be(string.Empty); } /// diff --git a/CaddyManager.Tests/Services/Caddy/CaddyServiceIntegrationTests.cs b/CaddyManager.Tests/Services/Caddy/CaddyServiceIntegrationTests.cs index 609b194..c01d414 100644 --- a/CaddyManager.Tests/Services/Caddy/CaddyServiceIntegrationTests.cs +++ b/CaddyManager.Tests/Services/Caddy/CaddyServiceIntegrationTests.cs @@ -1,7 +1,7 @@ -using CaddyManager.Configurations.Caddy; +using CaddyManager.Contracts.Configurations.Caddy; using CaddyManager.Contracts.Caddy; using CaddyManager.Contracts.Configurations; -using CaddyManager.Models.Caddy; +using CaddyManager.Contracts.Models.Caddy; using CaddyManager.Services.Caddy; using CaddyManager.Services.Configurations; using CaddyManager.Tests.TestUtilities; diff --git a/CaddyManager.Tests/Services/Caddy/CaddyServiceTests.cs b/CaddyManager.Tests/Services/Caddy/CaddyServiceTests.cs index 5a138d2..2b7f22d 100644 --- a/CaddyManager.Tests/Services/Caddy/CaddyServiceTests.cs +++ b/CaddyManager.Tests/Services/Caddy/CaddyServiceTests.cs @@ -1,7 +1,7 @@ -using CaddyManager.Configurations.Caddy; +using CaddyManager.Contracts.Configurations.Caddy; using CaddyManager.Contracts.Caddy; using CaddyManager.Contracts.Configurations; -using CaddyManager.Models.Caddy; +using CaddyManager.Contracts.Models.Caddy; using CaddyManager.Services.Caddy; using CaddyManager.Tests.TestUtilities; diff --git a/CaddyManager.Tests/Services/Configurations/ConfigurationsServiceIntegrationTests.cs b/CaddyManager.Tests/Services/Configurations/ConfigurationsServiceIntegrationTests.cs index 1a882a2..9e033a7 100644 --- a/CaddyManager.Tests/Services/Configurations/ConfigurationsServiceIntegrationTests.cs +++ b/CaddyManager.Tests/Services/Configurations/ConfigurationsServiceIntegrationTests.cs @@ -1,5 +1,5 @@ -using CaddyManager.Configurations.Caddy; -using CaddyManager.Configurations.Docker; +using CaddyManager.Contracts.Configurations.Caddy; +using CaddyManager.Contracts.Configurations.Docker; using CaddyManager.Services.Configurations; using Microsoft.Extensions.Configuration; diff --git a/CaddyManager.Tests/Services/Configurations/ConfigurationsServiceTests.cs b/CaddyManager.Tests/Services/Configurations/ConfigurationsServiceTests.cs index 985a4a2..d6ae000 100644 --- a/CaddyManager.Tests/Services/Configurations/ConfigurationsServiceTests.cs +++ b/CaddyManager.Tests/Services/Configurations/ConfigurationsServiceTests.cs @@ -1,5 +1,5 @@ -using CaddyManager.Configurations.Caddy; -using CaddyManager.Configurations.Docker; +using CaddyManager.Contracts.Configurations.Caddy; +using CaddyManager.Contracts.Configurations.Docker; using CaddyManager.Services.Configurations; using CaddyManager.Tests.TestUtilities; using Microsoft.Extensions.Configuration; diff --git a/CaddyManager.Tests/Services/Docker/DockerServiceTests.cs b/CaddyManager.Tests/Services/Docker/DockerServiceTests.cs index 4956622..fd414d9 100644 --- a/CaddyManager.Tests/Services/Docker/DockerServiceTests.cs +++ b/CaddyManager.Tests/Services/Docker/DockerServiceTests.cs @@ -1,4 +1,4 @@ -using CaddyManager.Configurations.Docker; +using CaddyManager.Contracts.Configurations.Docker; using CaddyManager.Contracts.Configurations; using CaddyManager.Services.Docker; using CaddyManager.Tests.TestUtilities; diff --git a/CaddyManager.sln b/CaddyManager.sln index 8cde887..c4cf6e5 100644 --- a/CaddyManager.sln +++ b/CaddyManager.sln @@ -12,6 +12,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CaddyManager.Contracts", "C EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CaddyManager.Services", "CaddyManager.Services\CaddyManager.Services.csproj", "{9F385FED-9B25-49EB-84F1-D944B7B91F35}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CaddyManager.Tests", "CaddyManager.Tests\CaddyManager.Tests.csproj", "{59569768-C5DB-4A6D-9675-A619158C0761}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -58,6 +60,18 @@ Global {9F385FED-9B25-49EB-84F1-D944B7B91F35}.Release|x64.Build.0 = Release|Any CPU {9F385FED-9B25-49EB-84F1-D944B7B91F35}.Release|x86.ActiveCfg = Release|Any CPU {9F385FED-9B25-49EB-84F1-D944B7B91F35}.Release|x86.Build.0 = Release|Any CPU + {59569768-C5DB-4A6D-9675-A619158C0761}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {59569768-C5DB-4A6D-9675-A619158C0761}.Debug|Any CPU.Build.0 = Debug|Any CPU + {59569768-C5DB-4A6D-9675-A619158C0761}.Debug|x64.ActiveCfg = Debug|Any CPU + {59569768-C5DB-4A6D-9675-A619158C0761}.Debug|x64.Build.0 = Debug|Any CPU + {59569768-C5DB-4A6D-9675-A619158C0761}.Debug|x86.ActiveCfg = Debug|Any CPU + {59569768-C5DB-4A6D-9675-A619158C0761}.Debug|x86.Build.0 = Debug|Any CPU + {59569768-C5DB-4A6D-9675-A619158C0761}.Release|Any CPU.ActiveCfg = Release|Any CPU + {59569768-C5DB-4A6D-9675-A619158C0761}.Release|Any CPU.Build.0 = Release|Any CPU + {59569768-C5DB-4A6D-9675-A619158C0761}.Release|x64.ActiveCfg = Release|Any CPU + {59569768-C5DB-4A6D-9675-A619158C0761}.Release|x64.Build.0 = Release|Any CPU + {59569768-C5DB-4A6D-9675-A619158C0761}.Release|x86.ActiveCfg = Release|Any CPU + {59569768-C5DB-4A6D-9675-A619158C0761}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE