Files
portal-api/tests/Feature/Api/Admin/CouponAdminTest.php

98 lines
3.4 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Feature\Api\Admin;
use App\Models\Coupon;
use App\Models\CouponRedemption;
use App\Models\Customer;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
use Tests\TestCase;
class CouponAdminTest extends TestCase
{
use RefreshDatabase;
private function admin(array $permissions): User
{
$role = Role::create(['name' => 'role-' . uniqid(), 'guard_name' => 'admin']);
foreach ($permissions as $name) {
$role->givePermissionTo(Permission::firstOrCreate(['name' => $name, 'guard_name' => 'admin']));
}
$admin = User::factory()->create();
$admin->assignRole($role);
return $admin;
}
private function payload(array $overrides = []): array
{
return array_merge([
'code' => 'welcome10',
'type' => 'percent',
'value' => 10,
'applies_to' => 'new',
'product_types' => ['vps'],
], $overrides);
}
public function test_crud_and_code_is_normalized(): void
{
$admin = $this->admin(['product-service.view', 'product-service.create', 'product-service.edit', 'product-service.destroy']);
$id = $this->actingAs($admin, 'admin')
->postJson('/api/v1/administrator/coupons', $this->payload())
->assertCreated()
->assertJsonPath('data.code', 'WELCOME10')
->json('data.id');
$this->putJson("/api/v1/administrator/coupons/{$id}", $this->payload(['value' => 15]))
->assertOk()->assertJsonPath('data.value', 15);
$this->getJson('/api/v1/administrator/coupons')->assertOk()->assertJsonPath('data.0.used_count', 0);
$this->deleteJson("/api/v1/administrator/coupons/{$id}")->assertOk();
}
public function test_validation_rejects_duplicate_code_and_percent_over_99(): void
{
$admin = $this->admin(['product-service.create']);
Coupon::create(['code' => 'DUP', 'type' => 'fixed', 'value' => 1000, 'applies_to' => 'new']);
$this->actingAs($admin, 'admin')
->postJson('/api/v1/administrator/coupons', $this->payload(['code' => 'dup']))
->assertStatus(422)->assertJsonValidationErrors('code');
$this->postJson('/api/v1/administrator/coupons', $this->payload(['value' => 100]))
->assertStatus(422)->assertJsonValidationErrors('value');
}
public function test_used_coupon_cannot_be_deleted(): void
{
$admin = $this->admin(['product-service.destroy']);
$coupon = Coupon::create(['code' => 'USED', 'type' => 'fixed', 'value' => 1000, 'applies_to' => 'new']);
CouponRedemption::create([
'coupon_id' => $coupon->id,
'customer_id' => Customer::factory()->create()->id,
'amount' => 1000,
]);
$this->actingAs($admin, 'admin')
->deleteJson("/api/v1/administrator/coupons/{$coupon->id}")
->assertStatus(422);
$this->assertNotNull(Coupon::find($coupon->id));
}
public function test_requires_permission(): void
{
Permission::firstOrCreate(['name' => 'product-service.view', 'guard_name' => 'admin']);
$this->actingAs($this->admin([]), 'admin')
->getJson('/api/v1/administrator/coupons')
->assertForbidden();
}
}