Files
fotospiel-app/tests/Feature/Support/SupportApiTest.php
Codex Agent 6e4656946c
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled
Expand support API integration tests and add load script
2026-01-28 21:49:16 +01:00

252 lines
7.4 KiB
PHP

<?php
namespace Tests\Feature\Support;
use App\Models\BlogCategory;
use App\Models\EventType;
use App\Models\Photo;
use App\Models\SuperAdminActionLog;
use App\Models\Tenant;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Bus;
use Illuminate\Support\Facades\Hash;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;
class SupportApiTest extends TestCase
{
use RefreshDatabase;
public function test_support_resources_require_authentication(): void
{
$response = $this->getJson('/api/v1/support/tenants');
$response->assertStatus(401);
}
public function test_support_resources_allow_super_admin_tokens(): void
{
$user = User::factory()->create([
'role' => 'super_admin',
]);
Tenant::factory()->create();
Sanctum::actingAs($user, ['support-admin', 'support:read']);
$response = $this->getJson('/api/v1/support/tenants');
$response->assertOk()
->assertJsonStructure(['data', 'meta']);
}
public function test_support_token_endpoint_issues_bearer_token_and_allows_api_access(): void
{
$user = User::factory()->create([
'role' => 'super_admin',
'password' => Hash::make('secret-password'),
]);
Tenant::factory()->create();
$response = $this->postJson('/api/v1/support/auth/token', [
'login' => $user->email,
'password' => 'secret-password',
]);
$response->assertOk()
->assertJsonStructure(['token', 'token_type', 'abilities', 'user']);
$token = $response->json('token');
$this->assertIsString($token);
$this->withHeader('Authorization', 'Bearer '.$token)
->getJson('/api/v1/support/tenants')
->assertOk()
->assertJsonStructure(['data', 'meta']);
}
public function test_support_requests_require_support_admin_ability(): void
{
$user = User::factory()->create([
'role' => 'super_admin',
]);
$token = $user->createToken('support-api', ['support:read'])->plainTextToken;
$response = $this->withHeader('Authorization', 'Bearer '.$token)
->getJson('/api/v1/support/tenants');
$response->assertStatus(403)
->assertJsonPath('error.code', 'support_forbidden');
}
public function test_support_write_requires_write_ability(): void
{
$user = User::factory()->create([
'role' => 'super_admin',
]);
$tenant = Tenant::factory()->create();
$token = $user->createToken('support-api', ['support-admin', 'support:read'])->plainTextToken;
$response = $this->withHeader('Authorization', 'Bearer '.$token)
->patchJson('/api/v1/support/tenants/'.$tenant->id, [
'data' => [
'slug' => 'not-allowed',
],
]);
$response->assertStatus(403)
->assertJsonPath('error.code', 'forbidden');
}
public function test_support_read_only_resource_rejects_deletes(): void
{
$user = User::factory()->create([
'role' => 'super_admin',
]);
$eventType = EventType::factory()->create();
$token = $user->createToken('support-api', ['support-admin', 'support:write'])->plainTextToken;
$response = $this->withHeader('Authorization', 'Bearer '.$token)
->deleteJson('/api/v1/support/event-types/'.$eventType->id);
$response->assertStatus(403)
->assertJsonPath('error.code', 'support_mutation_not_allowed');
}
public function test_expired_support_token_is_rejected(): void
{
$user = User::factory()->create([
'role' => 'super_admin',
]);
$token = $user->createToken('support-api', ['support-admin', 'support:read'], now()->subMinute())->plainTextToken;
$response = $this->withHeader('Authorization', 'Bearer '.$token)
->getJson('/api/v1/support/tenants');
$response->assertStatus(401);
}
public function test_support_resource_update_rejects_invalid_fields(): void
{
$user = User::factory()->create([
'role' => 'super_admin',
]);
$tenant = Tenant::factory()->create();
Sanctum::actingAs($user, ['support-admin', 'support:write']);
$response = $this->patchJson('/api/v1/support/tenants/'.$tenant->id, [
'data' => [
'name' => 'Unauthorized',
],
]);
$response->assertStatus(422)
->assertJsonPath('error.code', 'support_invalid_fields');
}
public function test_support_data_export_create_sets_user_and_dispatches_job(): void
{
$user = User::factory()->create([
'role' => 'super_admin',
]);
$tenant = Tenant::factory()->create();
Bus::fake();
Sanctum::actingAs($user, ['support-admin', 'support:ops']);
$response = $this->postJson('/api/v1/support/data-exports', [
'data' => [
'scope' => 'tenant',
'tenant_id' => $tenant->id,
'include_media' => true,
],
]);
$response->assertCreated()
->assertJsonPath('data.status', 'pending')
->assertJsonPath('data.user_id', $user->id)
->assertJsonPath('data.event_id', null);
Bus::assertDispatched(\App\Jobs\GenerateDataExport::class);
}
public function test_support_photo_reject_requires_moderation_notes(): void
{
$user = User::factory()->create([
'role' => 'super_admin',
]);
$photo = Photo::factory()->create();
Sanctum::actingAs($user, ['support-admin', 'support:write']);
$response = $this->patchJson('/api/v1/support/photos/'.$photo->id, [
'data' => [
'status' => 'rejected',
],
]);
$response->assertStatus(422)
->assertJsonValidationErrors(['moderation_notes']);
}
public function test_support_blog_post_create_requires_title_and_content(): void
{
$user = User::factory()->create([
'role' => 'super_admin',
]);
$category = BlogCategory::create([
'slug' => 'news',
'name' => ['de' => 'News', 'en' => 'News'],
'is_visible' => true,
]);
Sanctum::actingAs($user, ['support-admin', 'support:content']);
$response = $this->postJson('/api/v1/support/blog-posts', [
'data' => [
'blog_category_id' => $category->id,
'slug' => 'missing-title',
'is_published' => false,
],
]);
$response->assertStatus(422)
->assertJsonValidationErrors(['title', 'content']);
}
public function test_support_update_logs_audit_entry(): void
{
$user = User::factory()->create([
'role' => 'super_admin',
]);
$tenant = Tenant::factory()->create();
Sanctum::actingAs($user, ['support-admin', 'support:write']);
$response = $this->patchJson('/api/v1/support/tenants/'.$tenant->id, [
'data' => [
'slug' => 'support-updated',
],
]);
$response->assertOk();
$this->assertTrue(SuperAdminActionLog::query()->where('action', 'tenants.updated')->exists());
}
}