Deploy Ladill Link / deploy (push) Successful in 46s
Registration forms post to ladl.link first; Events-issued CSRF tokens cannot validate against the Link app session and caused token mismatch errors. Co-authored-by: Cursor <cursoragent@cursor.com>
237 lines
8.2 KiB
PHP
237 lines
8.2 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\ShortLink;
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Http;
|
|
use Illuminate\Support\Str;
|
|
use Tests\TestCase;
|
|
|
|
class LinkRedirectTest 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_direct_redirect_links_go_to_destination_url(): void
|
|
{
|
|
$user = $this->user();
|
|
ShortLink::create([
|
|
'user_id' => $user->id,
|
|
'slug' => 'direct1',
|
|
'source_app' => 'link',
|
|
'source_kind' => 'redirect',
|
|
'is_managed_here' => true,
|
|
'destination_url' => 'https://example.com/target',
|
|
'is_active' => true,
|
|
]);
|
|
|
|
$this->get('https://ladl.link/direct1')
|
|
->assertRedirect('https://example.com/target');
|
|
}
|
|
|
|
public function test_catalog_qr_links_proxy_to_platform_instead_of_bad_destination(): void
|
|
{
|
|
$user = $this->user();
|
|
ShortLink::create([
|
|
'user_id' => $user->id,
|
|
'slug' => 'qrpage',
|
|
'source_app' => 'qrplus',
|
|
'source_kind' => 'qr',
|
|
'is_managed_here' => false,
|
|
'destination_url' => 'https://ladl.link/qrpage · Link list page',
|
|
'is_active' => true,
|
|
]);
|
|
|
|
Http::fake([
|
|
'https://ladill.com/q/qrpage' => Http::response('<html>QR page</html>', 200),
|
|
]);
|
|
|
|
$this->get('https://ladl.link/qrpage')
|
|
->assertOk()
|
|
->assertSee('QR page');
|
|
|
|
Http::assertSent(function ($request) {
|
|
return $request->url() === 'https://ladill.com/q/qrpage'
|
|
&& $request->hasHeader('X-Ladill-Internal', '1');
|
|
});
|
|
}
|
|
|
|
public function test_transfer_qr_proxies_to_transfer_app_without_redirect_loop(): void
|
|
{
|
|
$user = $this->user();
|
|
ShortLink::create([
|
|
'user_id' => $user->id,
|
|
'slug' => 'mo4o0v1t',
|
|
'source_app' => 'transfer',
|
|
'source_kind' => 'qr',
|
|
'is_managed_here' => false,
|
|
'destination_url' => 'https://ladl.link/mo4o0v1t',
|
|
'is_active' => true,
|
|
]);
|
|
|
|
Http::fake([
|
|
'https://ladill.com/q/mo4o0v1t' => Http::response('', 302, [
|
|
'Location' => 'https://ladl.link/mo4o0v1t/transfer',
|
|
]),
|
|
'https://transfer.ladill.com/q/mo4o0v1t/transfer' => Http::response('<html>Transfer files</html>', 200),
|
|
]);
|
|
|
|
$this->get('https://ladl.link/mo4o0v1t')
|
|
->assertOk()
|
|
->assertSee('Transfer files');
|
|
|
|
Http::assertSent(function ($request) {
|
|
return $request->url() === 'https://transfer.ladill.com/q/mo4o0v1t/transfer'
|
|
&& $request->hasHeader('X-Ladill-Internal', '1');
|
|
});
|
|
}
|
|
|
|
public function test_event_qr_falls_back_to_events_app_when_platform_returns_404(): void
|
|
{
|
|
$user = $this->user();
|
|
ShortLink::create([
|
|
'user_id' => $user->id,
|
|
'slug' => 'sales-webinar',
|
|
'source_app' => 'events',
|
|
'source_kind' => 'qr',
|
|
'is_managed_here' => false,
|
|
'destination_url' => 'https://ladl.link/sales-webinar',
|
|
'is_active' => true,
|
|
]);
|
|
|
|
Http::fake([
|
|
'https://ladill.com/q/sales-webinar' => Http::response('Not found', 404),
|
|
'https://events.ladill.com/q/sales-webinar' => Http::response('<html>Event page</html>', 200),
|
|
]);
|
|
|
|
$this->get('https://ladl.link/sales-webinar')
|
|
->assertOk()
|
|
->assertSee('Event page');
|
|
|
|
Http::assertSent(function ($request) {
|
|
return $request->url() === 'https://events.ladill.com/q/sales-webinar'
|
|
&& $request->hasHeader('X-Ladill-Internal', '1');
|
|
});
|
|
}
|
|
|
|
public function test_event_registration_confirmation_proxies_directly_to_events_app(): void
|
|
{
|
|
$user = $this->user();
|
|
ShortLink::create([
|
|
'user_id' => $user->id,
|
|
'slug' => 'sales-webinar',
|
|
'source_app' => 'events',
|
|
'source_kind' => 'qr',
|
|
'is_managed_here' => false,
|
|
'destination_url' => 'https://ladl.link/sales-webinar',
|
|
'is_active' => true,
|
|
]);
|
|
|
|
Http::fake([
|
|
'https://events.ladill.com/q/sales-webinar/registered/QRE-TESTREF123456' => Http::response('<html>Registration confirmed</html>', 200),
|
|
]);
|
|
|
|
$this->get('https://ladl.link/sales-webinar/registered/QRE-TESTREF123456')
|
|
->assertOk()
|
|
->assertSee('Registration confirmed');
|
|
|
|
Http::assertSent(function ($request) {
|
|
return $request->url() === 'https://events.ladill.com/q/sales-webinar/registered/QRE-TESTREF123456'
|
|
&& $request->hasHeader('X-Ladill-Internal', '1');
|
|
});
|
|
|
|
Http::assertNotSent(function ($request) {
|
|
return str_starts_with($request->url(), 'https://ladill.com/q/sales-webinar/registered/');
|
|
});
|
|
}
|
|
|
|
public function test_event_registration_post_forwards_json_body_to_events(): void
|
|
{
|
|
$user = $this->user();
|
|
ShortLink::create([
|
|
'user_id' => $user->id,
|
|
'slug' => 'sales-webinar',
|
|
'source_app' => 'events',
|
|
'source_kind' => 'qr',
|
|
'is_managed_here' => false,
|
|
'destination_url' => 'https://ladl.link/sales-webinar',
|
|
'is_active' => true,
|
|
]);
|
|
|
|
Http::fake([
|
|
'https://events.ladill.com/q/sales-webinar/register' => function ($request) {
|
|
$payload = json_decode($request->body(), true);
|
|
|
|
return Http::response(json_encode([
|
|
'paid' => false,
|
|
'success_url' => 'https://ladl.link/sales-webinar/registered/QRE-TESTREF123456',
|
|
'badge_code' => 'BADGE123',
|
|
]), 200, ['Content-Type' => 'application/json']);
|
|
},
|
|
]);
|
|
|
|
$this->postJson('https://ladl.link/sales-webinar/register', [
|
|
'tier' => 'General Admission',
|
|
'attendee_name' => 'Jane Doe',
|
|
'attendee_email' => 'jane@example.com',
|
|
'attendee_phone' => '+233200000000',
|
|
])
|
|
->assertOk()
|
|
->assertJsonPath('success_url', 'https://ladl.link/sales-webinar/registered/QRE-TESTREF123456');
|
|
|
|
Http::assertSent(function ($request) {
|
|
if ($request->url() !== 'https://events.ladill.com/q/sales-webinar/register') {
|
|
return false;
|
|
}
|
|
|
|
$payload = json_decode($request->body(), true);
|
|
|
|
return is_array($payload)
|
|
&& ($payload['attendee_email'] ?? '') === 'jane@example.com'
|
|
&& ($payload['tier'] ?? '') === 'General Admission'
|
|
&& $request->hasHeader('X-Ladill-Internal', '1');
|
|
});
|
|
}
|
|
|
|
public function test_event_registration_post_does_not_require_link_app_csrf_token(): void
|
|
{
|
|
$user = $this->user();
|
|
ShortLink::create([
|
|
'user_id' => $user->id,
|
|
'slug' => 'sales-webinar',
|
|
'source_app' => 'events',
|
|
'source_kind' => 'qr',
|
|
'is_managed_here' => false,
|
|
'destination_url' => 'https://ladl.link/sales-webinar',
|
|
'is_active' => true,
|
|
]);
|
|
|
|
Http::fake([
|
|
'https://events.ladill.com/q/sales-webinar/register' => Http::response(json_encode([
|
|
'paid' => false,
|
|
'success_url' => 'https://ladl.link/sales-webinar/registered/QRE-TESTREF123456',
|
|
'badge_code' => 'BADGE123',
|
|
]), 200, ['Content-Type' => 'application/json']),
|
|
]);
|
|
|
|
$this->postJson('https://ladl.link/sales-webinar/register', [
|
|
'tier' => 'General Admission',
|
|
'attendee_name' => 'Jane Doe',
|
|
'attendee_email' => 'jane@example.com',
|
|
'attendee_phone' => '+233200000000',
|
|
])
|
|
->assertOk()
|
|
->assertJsonPath('badge_code', 'BADGE123');
|
|
}
|
|
}
|