all system emails look fresh now, plus added paddle portal debugging
This commit is contained in:
103
tests/Feature/BrandedMailableEmailsTest.php
Normal file
103
tests/Feature/BrandedMailableEmailsTest.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Mail\ContactRequest;
|
||||
use App\Models\PackagePurchase;
|
||||
use App\Models\Tenant;
|
||||
use App\Models\User;
|
||||
use App\Notifications\Customer\RefundReceipt;
|
||||
use App\Notifications\InactiveTenantDeletionWarning;
|
||||
use App\Notifications\Ops\PurchaseCreated;
|
||||
use App\Notifications\ResetPasswordNotification;
|
||||
use App\Notifications\UploadPipelineFailed;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Tests\TestCase;
|
||||
|
||||
class BrandedMailableEmailsTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_upload_pipeline_failed_uses_branded_view(): void
|
||||
{
|
||||
$notification = new UploadPipelineFailed([
|
||||
'job' => 'UploadJob',
|
||||
'queue' => 'uploads',
|
||||
'event_id' => 123,
|
||||
'photo_id' => 456,
|
||||
'exception' => 'ExampleException',
|
||||
]);
|
||||
|
||||
$mailMessage = $notification->toMail((object) []);
|
||||
|
||||
$this->assertInstanceOf(MailMessage::class, $mailMessage);
|
||||
$this->assertSame('emails.notifications.basic', $mailMessage->view);
|
||||
$this->assertArrayHasKey('lines', $mailMessage->viewData);
|
||||
}
|
||||
|
||||
public function test_inactive_tenant_deletion_warning_uses_branded_view(): void
|
||||
{
|
||||
$tenant = Tenant::factory()->create([
|
||||
'name' => 'Demo Tenant',
|
||||
]);
|
||||
|
||||
$notification = new InactiveTenantDeletionWarning($tenant, Carbon::now()->addDays(10));
|
||||
$mailMessage = $notification->toMail((object) []);
|
||||
|
||||
$this->assertInstanceOf(MailMessage::class, $mailMessage);
|
||||
$this->assertSame('emails.notifications.basic', $mailMessage->view);
|
||||
$this->assertArrayHasKey('cta', $mailMessage->viewData);
|
||||
}
|
||||
|
||||
public function test_refund_receipt_uses_branded_view(): void
|
||||
{
|
||||
$purchase = PackagePurchase::factory()->create();
|
||||
$notification = new RefundReceipt($purchase);
|
||||
$mailMessage = $notification->toMail((object) []);
|
||||
|
||||
$this->assertInstanceOf(MailMessage::class, $mailMessage);
|
||||
$this->assertSame('emails.notifications.basic', $mailMessage->view);
|
||||
$this->assertArrayHasKey('footer', $mailMessage->viewData);
|
||||
}
|
||||
|
||||
public function test_ops_purchase_created_uses_branded_view(): void
|
||||
{
|
||||
$purchase = PackagePurchase::factory()->create();
|
||||
$notification = new PurchaseCreated($purchase);
|
||||
$mailMessage = $notification->toMail((object) []);
|
||||
|
||||
$this->assertInstanceOf(MailMessage::class, $mailMessage);
|
||||
$this->assertSame('emails.notifications.basic', $mailMessage->view);
|
||||
}
|
||||
|
||||
public function test_reset_password_notification_uses_branded_view(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$notification = new ResetPasswordNotification('token-123');
|
||||
$mailMessage = $notification->toMail($user);
|
||||
|
||||
$this->assertInstanceOf(MailMessage::class, $mailMessage);
|
||||
$this->assertSame('emails.reset-password', $mailMessage->view);
|
||||
$this->assertArrayHasKey('resetUrl', $mailMessage->viewData);
|
||||
}
|
||||
|
||||
public function test_contact_request_email_uses_branded_layout(): void
|
||||
{
|
||||
Mail::fake();
|
||||
|
||||
$mail = new ContactRequest(
|
||||
name: 'Alex',
|
||||
email: 'alex@example.test',
|
||||
messageBody: 'Hello from the contact form.',
|
||||
);
|
||||
|
||||
Mail::to('support@example.test')->send($mail);
|
||||
|
||||
Mail::assertSent(ContactRequest::class, function (ContactRequest $sent) {
|
||||
return $sent->content()->view === 'emails.contact-request';
|
||||
});
|
||||
}
|
||||
}
|
||||
68
tests/Feature/Tenant/TenantBillingPortalTest.php
Normal file
68
tests/Feature/Tenant/TenantBillingPortalTest.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature\Tenant;
|
||||
|
||||
use App\Services\Paddle\Exceptions\PaddleException;
|
||||
use App\Services\Paddle\PaddleCustomerPortalService;
|
||||
use App\Services\Paddle\PaddleCustomerService;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Mockery;
|
||||
|
||||
class TenantBillingPortalTest extends TenantTestCase
|
||||
{
|
||||
protected function tearDown(): void
|
||||
{
|
||||
Mockery::close();
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function test_portal_logs_paddle_error_context(): void
|
||||
{
|
||||
$logged = [];
|
||||
Log::listen(function ($event) use (&$logged): void {
|
||||
$logged[] = [
|
||||
'level' => $event->level,
|
||||
'message' => $event->message,
|
||||
'context' => $event->context,
|
||||
];
|
||||
});
|
||||
|
||||
$customerService = Mockery::mock(PaddleCustomerService::class);
|
||||
$customerService->shouldReceive('ensureCustomerId')
|
||||
->once()
|
||||
->withArgs(fn ($tenant) => $tenant->is($this->tenant))
|
||||
->andReturn('ctm_test_123');
|
||||
$this->instance(PaddleCustomerService::class, $customerService);
|
||||
|
||||
$portalService = Mockery::mock(PaddleCustomerPortalService::class);
|
||||
$portalService->shouldReceive('createSession')
|
||||
->once()
|
||||
->with('ctm_test_123')
|
||||
->andThrow(new PaddleException('Paddle request failed with status 404', 404, [
|
||||
'error' => [
|
||||
'code' => 'entity_not_found',
|
||||
'message' => 'Not found',
|
||||
],
|
||||
]));
|
||||
$this->instance(PaddleCustomerPortalService::class, $portalService);
|
||||
|
||||
$response = $this->authenticatedRequest('POST', '/api/v1/tenant/billing/portal');
|
||||
|
||||
$response->assertStatus(502)
|
||||
->assertJson([
|
||||
'message' => 'Failed to create Paddle customer portal session.',
|
||||
]);
|
||||
|
||||
$matched = collect($logged)->contains(function (array $entry): bool {
|
||||
return $entry['level'] === 'warning'
|
||||
&& $entry['message'] === 'Failed to create Paddle customer portal session'
|
||||
&& ($entry['context']['tenant_id'] ?? null) === $this->tenant->id
|
||||
&& ($entry['context']['paddle_customer_id'] ?? null) === 'ctm_test_123'
|
||||
&& ($entry['context']['paddle_status'] ?? null) === 404
|
||||
&& ($entry['context']['paddle_error_code'] ?? null) === 'entity_not_found';
|
||||
});
|
||||
|
||||
$this->assertTrue($matched);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user