Hintergründe zum EventInvitePage Layout Customizer hinzugefügt. Badge und CTA entfernt, Textfelder zu Textareas gemacht. Geschenkgutscheine verbessert, E-Mail-Versand ergänzt + Resend + Confirmationseite mit Code-Copy und Link zur Package-Seite, die den Code als URL-Parameter enthält.
This commit is contained in:
52
tests/Feature/Api/GiftVoucherLookupTest.php
Normal file
52
tests/Feature/Api/GiftVoucherLookupTest.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature\Api;
|
||||
|
||||
use App\Models\GiftVoucher;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class GiftVoucherLookupTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_it_returns_voucher_by_checkout_id(): void
|
||||
{
|
||||
$voucher = GiftVoucher::factory()->create([
|
||||
'code' => 'GIFT-TESTCODE',
|
||||
'amount' => 59.00,
|
||||
'currency' => 'EUR',
|
||||
'paddle_checkout_id' => 'chk_look_123',
|
||||
'status' => GiftVoucher::STATUS_ISSUED,
|
||||
]);
|
||||
|
||||
$response = $this->getJson('/api/v1/marketing/gift-vouchers/lookup?checkout_id=chk_look_123');
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonPath('data.code', $voucher->code)
|
||||
->assertJsonPath('data.amount', 59)
|
||||
->assertJsonPath('data.currency', 'EUR');
|
||||
}
|
||||
|
||||
public function test_it_returns_voucher_by_code(): void
|
||||
{
|
||||
$voucher = GiftVoucher::factory()->create([
|
||||
'code' => 'GIFT-CODE',
|
||||
'amount' => 29.00,
|
||||
'currency' => 'EUR',
|
||||
]);
|
||||
|
||||
$response = $this->getJson('/api/v1/marketing/gift-vouchers/lookup?code=gift-code');
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonPath('data.code', $voucher->code)
|
||||
->assertJsonPath('data.amount', 29);
|
||||
}
|
||||
|
||||
public function test_it_requires_identifier(): void
|
||||
{
|
||||
$response = $this->getJson('/api/v1/marketing/gift-vouchers/lookup');
|
||||
|
||||
$response->assertStatus(422);
|
||||
}
|
||||
}
|
||||
41
tests/Feature/Api/GiftVoucherResendTest.php
Normal file
41
tests/Feature/Api/GiftVoucherResendTest.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature\Api;
|
||||
|
||||
use App\Models\GiftVoucher;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Tests\TestCase;
|
||||
use App\Mail\GiftVoucherIssued;
|
||||
|
||||
class GiftVoucherResendTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_it_resends_voucher_emails(): void
|
||||
{
|
||||
Mail::fake();
|
||||
config()->set('gift-vouchers.reminder_days', 0);
|
||||
config()->set('gift-vouchers.expiry_reminder_days', 0);
|
||||
|
||||
$voucher = GiftVoucher::factory()->create([
|
||||
'code' => 'GIFT-RESEND',
|
||||
'purchaser_email' => 'buyer@example.com',
|
||||
'recipient_email' => 'friend@example.com',
|
||||
]);
|
||||
|
||||
$response = $this->postJson('/api/v1/marketing/gift-vouchers/resend', [
|
||||
'code' => 'gift-resend',
|
||||
]);
|
||||
|
||||
$response->assertOk();
|
||||
Mail::assertQueued(GiftVoucherIssued::class, 2);
|
||||
}
|
||||
|
||||
public function test_it_requires_code(): void
|
||||
{
|
||||
$response = $this->postJson('/api/v1/marketing/gift-vouchers/resend', []);
|
||||
|
||||
$response->assertStatus(422);
|
||||
}
|
||||
}
|
||||
@@ -7,9 +7,11 @@ use App\Jobs\SyncCouponToPaddle;
|
||||
use App\Models\Coupon;
|
||||
use App\Models\GiftVoucher;
|
||||
use App\Models\Package;
|
||||
use App\Mail\GiftVoucherIssued;
|
||||
use App\Services\GiftVouchers\GiftVoucherService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Bus;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Tests\TestCase;
|
||||
|
||||
class GiftVoucherServiceTest extends TestCase
|
||||
@@ -80,4 +82,73 @@ class GiftVoucherServiceTest extends TestCase
|
||||
$this->assertSame(GiftVoucher::STATUS_REDEEMED, $voucher->refresh()->status);
|
||||
$this->assertNotNull($voucher->redeemed_at);
|
||||
}
|
||||
|
||||
public function test_it_sends_notifications_to_purchaser_and_recipient_once(): void
|
||||
{
|
||||
Mail::fake();
|
||||
Bus::fake([SyncCouponToPaddle::class]);
|
||||
config()->set('gift-vouchers.reminder_days', 0);
|
||||
config()->set('gift-vouchers.expiry_reminder_days', 0);
|
||||
|
||||
Package::factory()->create([
|
||||
'type' => 'endcustomer',
|
||||
'paddle_price_id' => 'pri_pkg_001',
|
||||
'price' => 29,
|
||||
]);
|
||||
|
||||
$payload = [
|
||||
'id' => 'txn_456',
|
||||
'currency_code' => 'EUR',
|
||||
'totals' => [
|
||||
'grand_total' => [
|
||||
'amount' => 2900,
|
||||
],
|
||||
],
|
||||
'metadata' => [
|
||||
'type' => 'gift_voucher',
|
||||
'purchaser_email' => 'buyer@example.com',
|
||||
'recipient_email' => 'friend@example.com',
|
||||
'app_locale' => 'de',
|
||||
],
|
||||
'checkout_id' => 'chk_notif',
|
||||
];
|
||||
|
||||
$service = $this->app->make(GiftVoucherService::class);
|
||||
$voucher = $service->issueFromPaddle($payload);
|
||||
|
||||
Mail::assertQueued(GiftVoucherIssued::class, 2);
|
||||
$this->assertTrue((bool) ($voucher->metadata['notifications_sent'] ?? false));
|
||||
|
||||
// Second call (duplicate webhook) should not resend
|
||||
$service->issueFromPaddle($payload);
|
||||
Mail::assertQueued(GiftVoucherIssued::class, 2);
|
||||
}
|
||||
|
||||
public function test_it_resolves_amount_from_tier_by_price_id(): void
|
||||
{
|
||||
config()->set('gift-vouchers.tiers', [
|
||||
[
|
||||
'key' => 'gift-standard-usd',
|
||||
'label' => 'Gift Standard (USD)',
|
||||
'amount' => 65.00,
|
||||
'currency' => 'USD',
|
||||
'paddle_price_id' => 'pri_usd_123',
|
||||
],
|
||||
]);
|
||||
|
||||
Bus::fake([SyncCouponToPaddle::class]);
|
||||
Mail::fake();
|
||||
|
||||
$payload = [
|
||||
'id' => 'txn_usd',
|
||||
'price_id' => 'pri_usd_123',
|
||||
'currency_code' => 'USD',
|
||||
];
|
||||
|
||||
$service = $this->app->make(GiftVoucherService::class);
|
||||
$voucher = $service->issueFromPaddle($payload);
|
||||
|
||||
$this->assertSame(65.00, (float) $voucher->amount);
|
||||
$this->assertSame('USD', $voucher->currency);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user