'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(); } }