Add device, platform, and country analytics to link show page.
Deploy Ladill Link / deploy (push) Successful in 32s
Deploy Ladill Link / deploy (push) Successful in 32s
Record parsed user-agent and geo data on clicks, then surface breakdowns and richer recent-click context on per-link and account analytics views. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\LinkClick;
|
||||
use App\Models\ShortLink;
|
||||
use App\Models\User;
|
||||
use App\Services\Link\LinkAnalyticsService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Str;
|
||||
use Tests\TestCase;
|
||||
|
||||
class LinkAnalyticsTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
private function user(): User
|
||||
{
|
||||
return User::create([
|
||||
'public_id' => (string) Str::uuid(),
|
||||
'name' => 'Test',
|
||||
'email' => 'test+'.uniqid().'@example.com',
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_redirect_records_device_browser_os_and_country(): void
|
||||
{
|
||||
$user = $this->user();
|
||||
ShortLink::create([
|
||||
'user_id' => $user->id,
|
||||
'slug' => 'tracked',
|
||||
'source_app' => 'link',
|
||||
'source_kind' => 'redirect',
|
||||
'is_managed_here' => true,
|
||||
'destination_url' => 'https://example.com/target',
|
||||
'is_active' => true,
|
||||
]);
|
||||
|
||||
$this->withHeaders([
|
||||
'User-Agent' => 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1',
|
||||
'CF-IPCountry' => 'GH',
|
||||
])->get('https://ladl.link/tracked')
|
||||
->assertRedirect('https://example.com/target');
|
||||
|
||||
$click = LinkClick::first();
|
||||
$this->assertNotNull($click);
|
||||
$this->assertSame('mobile', $click->device_type);
|
||||
$this->assertSame('Safari', $click->browser);
|
||||
$this->assertSame('iOS', $click->os);
|
||||
$this->assertSame('GH', $click->country);
|
||||
}
|
||||
|
||||
public function test_breakdown_for_link_groups_clicks_by_device(): void
|
||||
{
|
||||
$user = $this->user();
|
||||
$link = ShortLink::create([
|
||||
'user_id' => $user->id,
|
||||
'slug' => 'breakdown',
|
||||
'source_app' => 'link',
|
||||
'source_kind' => 'redirect',
|
||||
'is_managed_here' => true,
|
||||
'destination_url' => 'https://example.com',
|
||||
'is_active' => true,
|
||||
'clicks_total' => 2,
|
||||
'unique_clicks_total' => 2,
|
||||
]);
|
||||
|
||||
LinkClick::create([
|
||||
'short_link_id' => $link->id,
|
||||
'ip_hash' => 'a',
|
||||
'device_type' => 'mobile',
|
||||
'browser' => 'Chrome',
|
||||
'os' => 'Android',
|
||||
'country' => 'GH',
|
||||
'is_unique' => true,
|
||||
'clicked_at' => now(),
|
||||
]);
|
||||
LinkClick::create([
|
||||
'short_link_id' => $link->id,
|
||||
'ip_hash' => 'b',
|
||||
'device_type' => 'desktop',
|
||||
'browser' => 'Chrome',
|
||||
'os' => 'Windows',
|
||||
'country' => 'US',
|
||||
'is_unique' => true,
|
||||
'clicked_at' => now(),
|
||||
]);
|
||||
|
||||
$devices = app(LinkAnalyticsService::class)->breakdownForLink($link, 'device_type');
|
||||
|
||||
$this->assertCount(2, $devices);
|
||||
$labels = array_column($devices, 'label');
|
||||
$this->assertContains('Mobile', $labels);
|
||||
$this->assertContains('Desktop', $labels);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user