Files
isaacclad 95d73d1367
Deploy Ladill QR Plus / deploy (push) Successful in 1m6s
Add Campaigns module for grouping QR codes.
Let accounts organise codes by promo or launch, attach or detach codes, and view combined scan totals from the sidebar.
2026-07-16 20:43:02 +00:00

124 lines
3.6 KiB
PHP

<?php
namespace Tests\Feature;
use App\Http\Middleware\EnsurePlatformSession;
use App\Models\Campaign;
use App\Models\QrCode;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Str;
use Tests\TestCase;
class CampaignTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
$this->withoutMiddleware(EnsurePlatformSession::class);
if (method_exists($this, 'withoutVite')) {
$this->withoutVite();
}
}
private function user(): User
{
return User::create([
'public_id' => (string) Str::uuid(),
'name' => 'Owner',
'email' => 'owner+'.uniqid().'@example.com',
]);
}
private function code(User $user, array $attrs = []): QrCode
{
return QrCode::create(array_merge([
'user_id' => $user->id,
'short_code' => strtolower(Str::random(8)),
'type' => QrCode::TYPE_URL,
'label' => 'Test code',
'destination_url' => 'https://example.com',
'is_active' => true,
'scans_total' => 5,
'unique_scans_total' => 3,
], $attrs));
}
public function test_owner_can_create_campaign_and_attach_codes(): void
{
$user = $this->user();
$code = $this->code($user);
$this->actingAs($user)
->post(route('qr.campaigns.store'), [
'name' => 'Spring promo',
'description' => 'April flyers',
'status' => Campaign::STATUS_ACTIVE,
])
->assertRedirect();
$campaign = Campaign::first();
$this->assertNotNull($campaign);
$this->assertSame('Spring promo', $campaign->name);
$this->assertSame($user->id, $campaign->user_id);
$this->actingAs($user)
->post(route('qr.campaigns.attach', $campaign), [
'qr_code_ids' => [$code->id],
])
->assertRedirect()
->assertSessionHas('success');
$this->assertSame($campaign->id, $code->fresh()->campaign_id);
$this->actingAs($user)
->get(route('qr.campaigns.show', $campaign))
->assertOk()
->assertSee('Spring promo')
->assertSee($code->short_code);
}
public function test_owner_can_detach_and_delete_campaign(): void
{
$user = $this->user();
$campaign = Campaign::create([
'user_id' => $user->id,
'name' => 'Temp',
'status' => Campaign::STATUS_ACTIVE,
]);
$code = $this->code($user, ['campaign_id' => $campaign->id]);
$this->actingAs($user)
->delete(route('qr.campaigns.detach', [$campaign, $code]))
->assertRedirect();
$this->assertNull($code->fresh()->campaign_id);
$code->update(['campaign_id' => $campaign->id]);
$this->actingAs($user)
->delete(route('qr.campaigns.destroy', $campaign))
->assertRedirect(route('qr.campaigns.index'));
$this->assertDatabaseMissing('campaigns', ['id' => $campaign->id]);
$this->assertNull($code->fresh()->campaign_id);
}
public function test_other_user_cannot_view_campaign(): void
{
$owner = $this->user();
$other = $this->user();
$campaign = Campaign::create([
'user_id' => $owner->id,
'name' => 'Private',
'status' => Campaign::STATUS_ACTIVE,
]);
$this->actingAs($other)
->get(route('qr.campaigns.show', $campaign))
->assertForbidden();
}
}