Files
portal-api/tests/Feature/Api/Admin/MarketingEmailOptOutTest.php
T
baodev0andClaude Opus 5.5 bf78f3b810 feat: hồ sơ khách (ngày sinh, tỉnh/phường theo mã), gộp menu + nút tắt, thông báo theo uuid
- PUT v1/client/update: gender theo enum ClientGender (0 Nam/1 Nữ), thêm
  birthday (cột mới), province_code/ward_code validate theo bảng provinces/wards
  (phường phải thuộc tỉnh). Migration nạp dữ liệu hành chính 2025 từ
  province_ward_import.sql (chỉ bảng trống), API GET v1/provinces[/{code}/wards].
- CustomerObserver/OrderObserver log giá trị cũ bằng getRawOriginal: getOriginal
  trả enum object, nối chuỗi gây 500 khi khách đổi giới tính.
- ClientResource: các cờ trả boolean, CCCD chỉ trả cccd_updated (không lộ ảnh/số).
- GET v1/setting/menu trả cả items + quick_links, bỏ v1/setting/quick-links.
- Thông báo admin/khách tra theo uuid thay vì id tự tăng.
- Chặn gửi template marketing cho khách đã tắt nhận email marketing.
- Xoá ProvinceWardSeeder và Customer::$updatable không dùng.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 16:03:18 +07:00

90 lines
3.0 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Feature\Api\Admin;
use App\Jobs\Mail\SendMailCampaignRecipient;
use App\Models\Customer;
use App\Models\Template;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Queue;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
use Tests\TestCase;
class MarketingEmailOptOutTest extends TestCase
{
use RefreshDatabase;
private function admin(): User
{
$role = Role::create(['name' => 'role-' . uniqid(), 'guard_name' => 'admin']);
$role->givePermissionTo(Permission::firstOrCreate(['name' => 'mail-campaign.create', 'guard_name' => 'admin']));
$admin = User::factory()->create();
$admin->assignRole($role);
return $admin;
}
private function template(?string $key): Template
{
return Template::create([
'type_id' => 0,
'name' => 'T ' . uniqid(),
'key' => $key,
'format' => 'html',
'subject' => 'Ưu đãi',
'message' => '<p>Hello</p>',
'status' => 1,
]);
}
public function test_marketing_campaign_skips_opted_out_customers_but_system_template_does_not(): void
{
Queue::fake();
$admin = $this->admin();
$subscribed = Customer::factory()->create(['email_marketing' => 1]);
$optedOut = Customer::factory()->create(['email_marketing' => 0]);
$this->actingAs($admin, 'admin')
->postJson('/api/v1/administrator/mail-campaigns', [
'template_id' => $this->template(null)->id,
'recipient_type' => 'selected',
'uuids' => [$subscribed->uuid, $optedOut->uuid],
'emails' => [strtoupper($optedOut->email)],
])
->assertOk()
->assertJsonPath('data.total_recipients', 1);
Queue::assertPushed(SendMailCampaignRecipient::class, 1);
$this->actingAs($admin, 'admin')
->postJson('/api/v1/administrator/mail-campaigns', [
'template_id' => $this->template('service_renewal_reminder')->id,
'recipient_type' => 'selected',
'uuids' => [$optedOut->uuid],
])
->assertOk()
->assertJsonPath('data.total_recipients', 1);
}
public function test_marketing_campaign_with_only_opted_out_recipients_is_rejected(): void
{
Queue::fake();
$optedOut = Customer::factory()->create(['email_marketing' => 0]);
$this->actingAs($this->admin(), 'admin')
->postJson('/api/v1/administrator/mail-campaigns', [
'subject' => 'Tin tức',
'message' => '<p>Hi</p>',
'recipient_type' => 'selected',
'uuids' => [$optedOut->uuid],
])
->assertStatus(422);
Queue::assertNotPushed(SendMailCampaignRecipient::class);
}
}