Files
e-ticket/tests/Service/AnalyticsCryptoServiceTest.php
Serreau Jovann 6438afadbf Add first-party analytics tracker with encrypted transmissions
Core system:
- AnalyticsUniqId entity (visitor identity with device/os/browser parsing)
- AnalyticsEvent entity (page views linked to visitor)
- POST /t endpoint with AES-256-GCM encrypted payloads
- HMAC-SHA256 visitor hash for anti-tampering
- Async processing via Messenger
- JS module: auto page_view tracking, setAuth for logged users
- Encryption key shared via data-k attribute on body
- setAuth only triggers when cookie consent is accepted
- Clean CSP: remove old tracker domains (Cloudflare, Umami)

100% first-party, no cookies, invisible to adblockers, RGPD-friendly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:07 +01:00

86 lines
2.6 KiB
PHP

<?php
namespace App\Tests\Service;
use App\Service\AnalyticsCryptoService;
use PHPUnit\Framework\TestCase;
class AnalyticsCryptoServiceTest extends TestCase
{
private AnalyticsCryptoService $service;
protected function setUp(): void
{
$this->service = new AnalyticsCryptoService('test_secret_key_for_analytics');
}
public function testEncryptDecryptRoundTrip(): void
{
$data = ['uid' => 'abc-123', 'url' => '/test', 'title' => 'Test Page'];
$encrypted = $this->service->encrypt($data);
self::assertNotEmpty($encrypted);
$decrypted = $this->service->decrypt($encrypted);
self::assertSame($data, $decrypted);
}
public function testDecryptInvalidPayloadReturnsNull(): void
{
self::assertNull($this->service->decrypt('invalid_base64'));
self::assertNull($this->service->decrypt(base64_encode('short')));
}
public function testDecryptTamperedPayloadReturnsNull(): void
{
$encrypted = $this->service->encrypt(['test' => true]);
$tampered = substr($encrypted, 0, -2).'AA';
self::assertNull($this->service->decrypt($tampered));
}
public function testGenerateAndVerifyVisitorHash(): void
{
$uid = 'test-uid-123';
$hash = $this->service->generateVisitorHash($uid);
self::assertNotEmpty($hash);
self::assertTrue($this->service->verifyVisitorHash($uid, $hash));
}
public function testVerifyVisitorHashRejectsTampered(): void
{
$uid = 'test-uid-123';
$hash = $this->service->generateVisitorHash($uid);
self::assertFalse($this->service->verifyVisitorHash('different-uid', $hash));
self::assertFalse($this->service->verifyVisitorHash($uid, 'wrong_hash'));
}
public function testGetKeyForJsReturnsBase64(): void
{
$key = $this->service->getKeyForJs();
self::assertNotEmpty($key);
self::assertNotFalse(base64_decode($key, true));
}
public function testDifferentSecretsProduceDifferentKeys(): void
{
$service2 = new AnalyticsCryptoService('different_secret');
$uid = 'test-uid';
$hash1 = $this->service->generateVisitorHash($uid);
$hash2 = $service2->generateVisitorHash($uid);
self::assertNotSame($hash1, $hash2);
}
public function testEncryptedDataCannotBeDecryptedByDifferentKey(): void
{
$service2 = new AnalyticsCryptoService('different_secret');
$encrypted = $this->service->encrypt(['test' => true]);
self::assertNull($service2->decrypt($encrypted));
}
}