Expand support API integration tests and add load script
This commit is contained in:
47
scripts/load/support-api-k6.js
Normal file
47
scripts/load/support-api-k6.js
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import http from 'k6/http'
|
||||||
|
import { check, sleep } from 'k6'
|
||||||
|
|
||||||
|
const BASE_URL = __ENV.SUPPORT_API_BASE_URL || 'http://localhost'
|
||||||
|
const TOKEN = __ENV.SUPPORT_API_TOKEN || ''
|
||||||
|
const DEFAULT_SLEEP = __ENV.SUPPORT_API_SLEEP || '1'
|
||||||
|
|
||||||
|
if (!TOKEN) {
|
||||||
|
throw new Error('SUPPORT_API_TOKEN is required')
|
||||||
|
}
|
||||||
|
|
||||||
|
export const options = {
|
||||||
|
vus: Number(__ENV.SUPPORT_API_VUS || 10),
|
||||||
|
duration: __ENV.SUPPORT_API_DURATION || '1m',
|
||||||
|
thresholds: {
|
||||||
|
http_req_failed: ['rate<0.01'],
|
||||||
|
http_req_duration: ['p(95)<500'],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
function authHeaders() {
|
||||||
|
return {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${TOKEN}`,
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function () {
|
||||||
|
const listTenants = http.get(`${BASE_URL}/api/v1/support/tenants?per_page=25`, authHeaders())
|
||||||
|
check(listTenants, {
|
||||||
|
'list tenants 200': (res) => res.status === 200,
|
||||||
|
})
|
||||||
|
|
||||||
|
const listEvents = http.get(`${BASE_URL}/api/v1/support/events?per_page=25`, authHeaders())
|
||||||
|
check(listEvents, {
|
||||||
|
'list events 200': (res) => res.status === 200,
|
||||||
|
})
|
||||||
|
|
||||||
|
const listPhotos = http.get(`${BASE_URL}/api/v1/support/photos?per_page=25`, authHeaders())
|
||||||
|
check(listPhotos, {
|
||||||
|
'list photos 200': (res) => res.status === 200,
|
||||||
|
})
|
||||||
|
|
||||||
|
sleep(Number(DEFAULT_SLEEP))
|
||||||
|
}
|
||||||
@@ -3,12 +3,14 @@
|
|||||||
namespace Tests\Feature\Support;
|
namespace Tests\Feature\Support;
|
||||||
|
|
||||||
use App\Models\BlogCategory;
|
use App\Models\BlogCategory;
|
||||||
|
use App\Models\EventType;
|
||||||
use App\Models\Photo;
|
use App\Models\Photo;
|
||||||
use App\Models\SuperAdminActionLog;
|
use App\Models\SuperAdminActionLog;
|
||||||
use App\Models\Tenant;
|
use App\Models\Tenant;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
use Illuminate\Support\Facades\Bus;
|
use Illuminate\Support\Facades\Bus;
|
||||||
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Laravel\Sanctum\Sanctum;
|
use Laravel\Sanctum\Sanctum;
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
@@ -39,6 +41,100 @@ class SupportApiTest extends TestCase
|
|||||||
->assertJsonStructure(['data', 'meta']);
|
->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
|
public function test_support_resource_update_rejects_invalid_fields(): void
|
||||||
{
|
{
|
||||||
$user = User::factory()->create([
|
$user = User::factory()->create([
|
||||||
|
|||||||
Reference in New Issue
Block a user