refactor: update Blazor testing guidelines and improve regex for hostname parsing in Caddy configuration
Some checks failed
Caddy Manager CI build / docker (push) Failing after 51s

This commit is contained in:
2025-07-23 15:29:00 +07:00
parent 063ed041b0
commit 24f76f8572
3 changed files with 39 additions and 11 deletions

View File

@@ -32,7 +32,7 @@ alwaysApply: true
## Testing and Debugging ## Testing and Debugging
- All unit testing and integration testing should be done in Cursor ide - All unit testing and integration testing should be done in Cursor ide
- Test Blazor components and services using xUnit - Test services, unit and integration, using xUnit
- Use Moq for mocking dependencies during tests - Use Moq for mocking dependencies during tests
- Debug Blazor UI issues using browser developer tools and Cursor ide's debugging tools for backend and server-side issues - Debug Blazor UI issues using browser developer tools and Cursor ide's debugging tools for backend and server-side issues
- For performance profiling and optimization, rely on Cursor ide's diagnostics tools - For performance profiling and optimization, rely on Cursor ide's diagnostics tools

View File

@@ -8,9 +8,11 @@ public partial class CaddyConfigurationParsingService: ICaddyConfigurationParsin
{ {
/// <summary> /// <summary>
/// Regex to help parse hostnames from a Caddyfile. /// Regex to help parse hostnames from a Caddyfile.
/// This regex only matches hostname declarations at the beginning of lines (column 1 after optional whitespace)
/// and excludes nested directives like "reverse_proxy target {".
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[GeneratedRegex(@"(?m)^\s*([^\{\r\n]+?)\s*\{", RegexOptions.Multiline)] [GeneratedRegex(@"(?m)^([^\s\{\r\n][^\{\r\n]*?)\s*\{", RegexOptions.Multiline)]
private static partial Regex HostnamesRegex(); private static partial Regex HostnamesRegex();
/// <summary> /// <summary>
@@ -67,8 +69,8 @@ public partial class CaddyConfigurationParsingService: ICaddyConfigurationParsin
foreach (Match match in matches) foreach (Match match in matches)
{ {
var parts = match.Value.TrimEnd('}').Trim().Split(' '); // Use the captured group which contains the target (e.g., pikachu:3011)
var targetPart = parts.LastOrDefault(string.Empty); var targetPart = match.Groups[1].Value.Trim();
if (string.IsNullOrEmpty(targetPart)) continue; if (string.IsNullOrEmpty(targetPart)) continue;
var targetComponents = targetPart.Split(':'); var targetComponents = targetPart.Split(':');

View File

@@ -74,11 +74,9 @@ public class CaddyConfigurationParsingServiceTests
// Assert // Assert
result.Should().NotBeNull(); result.Should().NotBeNull();
result.Should().HaveCount(4); // Updated to reflect correct parsing of labels before blocks result.Should().HaveCount(2); // Should only return outermost hostname declarations
result.Should().Contain("api.example.com"); result.Should().Contain("api.example.com");
result.Should().Contain("app.example.com"); result.Should().Contain("app.example.com");
result.Should().Contain("route /v1/*");
result.Should().Contain("route /v2/*");
} }
/// <summary> /// <summary>
@@ -522,12 +520,9 @@ app.example.com {
// Assert // Assert
result.Should().NotBeNull(); result.Should().NotBeNull();
result.Should().HaveCount(5); result.Should().HaveCount(2); // Should only return outermost hostname declarations
result.Should().Contain("api.example.com"); result.Should().Contain("api.example.com");
result.Should().Contain("app.example.com"); result.Should().Contain("app.example.com");
result.Should().Contain("header");
result.Should().Contain("@cors");
result.Should().Contain("tls");
} }
/// <summary> /// <summary>
@@ -669,5 +664,36 @@ api.test {
stopwatch.ElapsedMilliseconds.Should().BeLessThan(1000); // Should process in under 1 second stopwatch.ElapsedMilliseconds.Should().BeLessThan(1000); // Should process in under 1 second
} }
/// <summary>
/// Tests the parsing issue where the provided configuration is incorrectly parsed as 2 sites and 0 ports
/// instead of 1 site and 1 port.
/// </summary>
[Fact]
public void GetHostnamesAndPortsFromCaddyfileContent_WithProvidedConfiguration_ReturnsCorrectSiteAndPort()
{
// Arrange
var caddyfileContent = @"pika-auth.duydao.org {
reverse_proxy pikachu:3011 {
header_down X-Frame-Options """"
}
encode zstd gzip
}";
// Act
var hostnames = _service.GetHostnamesFromCaddyfileContent(caddyfileContent);
var ports = _service.GetReverseProxyPortsFromCaddyfileContent(caddyfileContent);
// Assert - Should have 1 site and 1 port
hostnames.Should().NotBeNull();
hostnames.Should().HaveCount(1);
hostnames.Should().Contain("pika-auth.duydao.org");
ports.Should().NotBeNull();
ports.Should().HaveCount(1);
ports.Should().Contain(3011);
}
#endregion #endregion
} }