refactor: use DTO and terminate middleware for better performance

- Add PageviewData readonly DTO class for type safety
- Update AnalyticsClient to accept PageviewData instead of array
- Move analytics sending to terminate() method (runs after response sent)
- Update all tests for new DTO pattern
This commit is contained in:
mathiaspalmqvist committed 2026-01-03 15:09:48 +01:00
1 parent 448ac3e4cf
commit e3911ca12c
6 files changed
+154 -116

No files matched your search

+84 -48
View File
@@ -1,6 +1,7 @@
<?php
use Illuminate\Support\Facades\Http;
use Mattitja\Analytics\Data\PageviewData;
use Mattitja\Analytics\Services\AnalyticsClient;
beforeEach(function () {
@@ -9,20 +10,26 @@ beforeEach(function () {
it('sends analytics data to the correct endpoint', function () {
$client = new AnalyticsClient;
$data = [
'k' => 'test-site-key',
'u' => 'https://example.com/test',
'r' => 'https://google.com',
'ip' => '192.168.1.1',
'ua' => 'Mozilla/5.0 Chrome',
];
$data = new PageviewData(
siteKey: 'testsiteky',
url: 'https://example.com/test',
ip: '192.168.1.1',
userAgent: 'Mozilla/5.0 Chrome',
referrer: 'https://google.com',
);
$client->send($data);
Http::assertSent(function ($request) use ($data) {
Http::assertSent(function ($request) {
return $request->url() === 'https://analytics.mattitja.cloud/api/send' &&
$request->method() === 'POST' &&
$request->data() === $data;
$request->data() === [
'k' => 'testsiteky',
'u' => 'https://example.com/test',
'ip' => '192.168.1.1',
'ua' => 'Mozilla/5.0 Chrome',
'r' => 'https://google.com',
];
});
});
@@ -32,43 +39,57 @@ it('handles API failures gracefully', function () {
]);
$client = new AnalyticsClient;
$data = [
'k' => 'test-site-key',
'u' => 'https://example.com/test',
'r' => 'https://google.com',
'ip' => '192.168.1.1',
'ua' => 'Mozilla/5.0 Chrome',
];
$data = new PageviewData(
siteKey: 'testsiteky',
url: 'https://example.com/test',
ip: '192.168.1.1',
userAgent: 'Mozilla/5.0 Chrome',
referrer: 'https://google.com',
);
expect(fn () => $client->send($data))->not->toThrow(Exception::class);
});
it('uses hardcoded timeout', function () {
it('sends data with correct site key', function () {
$client = new AnalyticsClient;
$data = [
'k' => 'test-site-key',
'u' => 'https://example.com/test',
'r' => '',
'ip' => '192.168.1.1',
'ua' => 'Mozilla/5.0 Chrome',
];
$data = new PageviewData(
siteKey: 'testsiteky',
url: 'https://example.com/test',
ip: '192.168.1.1',
userAgent: 'Mozilla/5.0 Chrome',
);
$client->send($data);
Http::assertSent(function ($request) {
return $request->data()['k'] === 'test-site-key';
return $request->data()['k'] === 'testsiteky';
});
});
it('skips sending when required data fields are missing', function () {
it('skips sending when required fields are empty', function () {
$client = new AnalyticsClient;
// Should not throw exceptions, just skip silently
$client->send([]);
$client->send(['k' => 'test']);
$client->send(['k' => 'test', 'u' => 'url', 'ip' => '1.1.1.1']);
$client->send(new PageviewData(
siteKey: '',
url: 'https://example.com',
ip: '192.168.1.1',
userAgent: 'Mozilla/5.0',
));
$client->send(new PageviewData(
siteKey: 'testsiteky',
url: '',
ip: '192.168.1.1',
userAgent: 'Mozilla/5.0',
));
$client->send(new PageviewData(
siteKey: 'testsiteky',
url: 'https://example.com',
ip: '',
userAgent: 'Mozilla/5.0',
));
// No HTTP requests should be sent for invalid data
Http::assertNothingSent();
});
@@ -76,31 +97,46 @@ it('skips sending when URL exceeds 512 characters', function () {
$client = new AnalyticsClient;
$longUrl = 'https://example.com/'.str_repeat('a', 500);
$client->send([
'k' => 'testsiteky',
'u' => $longUrl,
'ip' => '192.168.1.1',
'ua' => 'Mozilla/5.0 Chrome',
]);
$client->send(new PageviewData(
siteKey: 'testsiteky',
url: $longUrl,
ip: '192.168.1.1',
userAgent: 'Mozilla/5.0 Chrome',
));
Http::assertNothingSent();
});
it('filters out empty referrer URLs', function () {
it('excludes empty referrer from payload', function () {
$client = new AnalyticsClient;
$data = [
'k' => 'test-site-key',
'u' => 'https://example.com/test',
'r' => '',
'ip' => '192.168.1.1',
'ua' => 'Mozilla/5.0 Chrome',
];
$data = new PageviewData(
siteKey: 'testsiteky',
url: 'https://example.com/test',
ip: '192.168.1.1',
userAgent: 'Mozilla/5.0 Chrome',
referrer: '',
);
$client->send($data);
Http::assertSent(function ($request) {
$sentData = $request->data();
return ! isset($sentData['r']);
return ! isset($request->data()['r']);
});
});
it('excludes null referrer from payload', function () {
$client = new AnalyticsClient;
$data = new PageviewData(
siteKey: 'testsiteky',
url: 'https://example.com/test',
ip: '192.168.1.1',
userAgent: 'Mozilla/5.0 Chrome',
referrer: null,
);
$client->send($data);
Http::assertSent(function ($request) {
return ! isset($request->data()['r']);
});
});