Remove WireGuard integration from production deployment to simplify infrastructure: - Remove docker-compose-direct-access.yml (VPN-bound services) - Remove VPN-only middlewares from Grafana, Prometheus, Portainer - Remove WireGuard middleware definitions from Traefik - Remove WireGuard IPs (10.8.0.0/24) from Traefik forwarded headers All monitoring services now publicly accessible via subdomains: - grafana.michaelschiemer.de (with Grafana native auth) - prometheus.michaelschiemer.de (with Basic Auth) - portainer.michaelschiemer.de (with Portainer native auth) All services use Let's Encrypt SSL certificates via Traefik.
165 lines
5.0 KiB
PHP
165 lines
5.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/../../vendor/autoload.php';
|
|
|
|
use App\Framework\QrCode\QrCodeGenerator;
|
|
use App\Framework\QrCode\ErrorCorrection\ReedSolomonEncoder;
|
|
use App\Framework\QrCode\ValueObjects\ErrorCorrectionLevel;
|
|
use App\Framework\QrCode\ValueObjects\QrCodeConfig;
|
|
use App\Framework\QrCode\ValueObjects\QrCodeVersion;
|
|
use App\Framework\QrCode\ValueObjects\EncodingMode;
|
|
|
|
echo "=== Encoding Logic Validation with Multiple Test Cases ===\n\n";
|
|
|
|
// Test cases with known expected results
|
|
$testCases = [
|
|
[
|
|
'data' => 'HELLO',
|
|
'version' => 1,
|
|
'level' => ErrorCorrectionLevel::M,
|
|
'mode' => EncodingMode::BYTE,
|
|
'description' => 'Short text, Version 1, Level M'
|
|
],
|
|
[
|
|
'data' => 'HELLO WORLD',
|
|
'version' => 1,
|
|
'level' => ErrorCorrectionLevel::M,
|
|
'mode' => EncodingMode::BYTE,
|
|
'description' => 'Medium text, Version 1, Level M'
|
|
],
|
|
[
|
|
'data' => 'A',
|
|
'version' => 1,
|
|
'level' => ErrorCorrectionLevel::M,
|
|
'mode' => EncodingMode::BYTE,
|
|
'description' => 'Single character, Version 1, Level M'
|
|
],
|
|
[
|
|
'data' => '12345',
|
|
'version' => 1,
|
|
'level' => ErrorCorrectionLevel::M,
|
|
'mode' => EncodingMode::NUMERIC,
|
|
'description' => 'Numeric data, Version 1, Level M'
|
|
],
|
|
[
|
|
'data' => 'HELLO123',
|
|
'version' => 1,
|
|
'level' => ErrorCorrectionLevel::M,
|
|
'mode' => EncodingMode::ALPHANUMERIC,
|
|
'description' => 'Alphanumeric data, Version 1, Level M'
|
|
],
|
|
];
|
|
|
|
foreach ($testCases as $testCase) {
|
|
echo "=== Test: {$testCase['description']} ===\n";
|
|
echo "Data: '{$testCase['data']}'\n";
|
|
|
|
$config = new QrCodeConfig(
|
|
version: QrCodeVersion::fromNumber($testCase['version']),
|
|
errorCorrectionLevel: $testCase['level'],
|
|
encodingMode: $testCase['mode']
|
|
);
|
|
|
|
// Generate QR code
|
|
$matrix = QrCodeGenerator::generate($testCase['data'], $config);
|
|
|
|
// Get encoding info
|
|
$ecInfo = ReedSolomonEncoder::getECInfo(
|
|
$config->version->getVersionNumber(),
|
|
$config->errorCorrectionLevel->value
|
|
);
|
|
|
|
echo "Version: {$testCase['version']}\n";
|
|
echo "Error Correction Level: {$testCase['level']->value}\n";
|
|
echo "Encoding Mode: {$testCase['mode']->value}\n";
|
|
echo "Data codewords: {$ecInfo['dataCodewords']}\n";
|
|
echo "EC codewords: {$ecInfo['ecCodewords']}\n";
|
|
echo "Total codewords: {$ecInfo['totalCodewords']}\n";
|
|
echo "Matrix size: {$matrix->getSize()}x{$matrix->getSize()}\n";
|
|
|
|
// Validate matrix structure
|
|
$size = $matrix->getSize();
|
|
$expectedSize = 21 + (($testCase['version'] - 1) * 4);
|
|
|
|
if ($size === $expectedSize) {
|
|
echo "✅ Matrix size correct\n";
|
|
} else {
|
|
echo "❌ Matrix size incorrect: got {$size}, expected {$expectedSize}\n";
|
|
}
|
|
|
|
// Check finder patterns
|
|
$finderPatterns = [
|
|
[0, 0], // Top-left
|
|
[0, $size - 7], // Top-right
|
|
[$size - 7, 0], // Bottom-left
|
|
];
|
|
|
|
$finderPatternOk = true;
|
|
foreach ($finderPatterns as [$startRow, $startCol]) {
|
|
// Check finder pattern structure (7x7)
|
|
for ($r = 0; $r < 7; $r++) {
|
|
for ($c = 0; $c < 7; $c++) {
|
|
$row = $startRow + $r;
|
|
$col = $startCol + $c;
|
|
$isDark = $matrix->getModuleAt($row, $col)->isDark();
|
|
|
|
// Finder pattern: 3x3 dark square, 1x1 light, 3x3 dark
|
|
$expectedDark = ($r < 3 && $c < 3) || ($r >= 4 && $c < 3) ||
|
|
($r < 3 && $c >= 4) || ($r >= 4 && $c >= 4) ||
|
|
($r === 0 || $r === 6 || $c === 0 || $c === 6);
|
|
|
|
if ($isDark !== $expectedDark) {
|
|
$finderPatternOk = false;
|
|
break 2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($finderPatternOk) {
|
|
echo "✅ Finder patterns correct\n";
|
|
} else {
|
|
echo "❌ Finder patterns incorrect\n";
|
|
}
|
|
|
|
// Check timing patterns
|
|
$timingOk = true;
|
|
$timingRow = 6;
|
|
$timingCol = 6;
|
|
|
|
// Horizontal timing (row 6, cols 8 to size-9)
|
|
for ($col = 8; $col < $size - 8; $col++) {
|
|
$expectedDark = (($col - 8) % 2) === 0;
|
|
$isDark = $matrix->getModuleAt($timingRow, $col)->isDark();
|
|
if ($isDark !== $expectedDark) {
|
|
$timingOk = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Vertical timing (col 6, rows 8 to size-9)
|
|
for ($row = 8; $row < $size - 8; $row++) {
|
|
$expectedDark = (($row - 8) % 2) === 0;
|
|
$isDark = $matrix->getModuleAt($row, $timingCol)->isDark();
|
|
if ($isDark !== $expectedDark) {
|
|
$timingOk = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ($timingOk) {
|
|
echo "✅ Timing patterns correct\n";
|
|
} else {
|
|
echo "❌ Timing patterns incorrect\n";
|
|
}
|
|
|
|
echo "\n";
|
|
}
|
|
|
|
echo "=== Summary ===\n";
|
|
echo "All test cases completed. Check output above for any errors.\n";
|
|
|
|
|