BastionSSO/tests/Feature/TicketFeatureTest.php

160 lines
5.6 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\Ticket;
use App\Models\TicketCategory;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
use Tests\TestCase;
class TicketFeatureTest extends TestCase
{
use RefreshDatabase;
public function test_user_can_create_and_reply_to_own_ticket(): void
{
$user = $this->userWithPermissions(['tickets.use']);
$category = TicketCategory::query()->create(['name' => '账号问题', 'is_active' => true]);
$create = $this->actingAs($user, 'api')->postJson('/tickets', [
'ticket_category_id' => $category->id,
'title' => '无法登录',
'content' => '登录失败',
]);
$create
->assertCreated()
->assertJsonPath('data.title', '无法登录')
->assertJsonPath('data.messages.0.content', '登录失败');
$ticketId = (int) $create->json('data.id');
$reply = $this->actingAs($user, 'api')->postJson('/tickets/'.$ticketId.'/messages', [
'content' => '补充信息',
]);
$reply
->assertCreated()
->assertJsonPath('data.sender_type', 'user');
$detail = $this->actingAs($user, 'api')->getJson('/tickets/'.$ticketId);
$detail
->assertOk()
->assertJsonPath('data.messages.1.content', '补充信息');
}
public function test_user_cannot_view_other_users_ticket(): void
{
$owner = $this->userWithPermissions(['tickets.use']);
$other = $this->userWithPermissions(['tickets.use']);
$category = TicketCategory::query()->create(['name' => '资源申请', 'is_active' => true]);
$ticket = Ticket::query()->create([
'user_id' => $owner->id,
'ticket_category_id' => $category->id,
'title' => '申请资源',
'content' => '需要资源',
'status' => Ticket::StatusOpen,
]);
$response = $this->actingAs($other, 'api')->getJson('/tickets/'.$ticket->id);
$response->assertStatus(403);
}
public function test_admin_can_manage_categories_update_and_reply_ticket(): void
{
$admin = $this->userWithPermissions(['platform.tickets.view', 'platform.tickets.manage']);
$owner = $this->userWithPermissions(['tickets.use']);
$category = TicketCategory::query()->create(['name' => '旧分类', 'is_active' => true]);
$ticket = Ticket::query()->create([
'user_id' => $owner->id,
'ticket_category_id' => $category->id,
'title' => '问题',
'content' => '内容',
'status' => Ticket::StatusOpen,
]);
$createdCategory = $this->actingAs($admin, 'api')->postJson('/ticket-categories', [
'name' => '新分类',
'description' => '分类说明',
'is_active' => true,
]);
$createdCategory->assertCreated()->assertJsonPath('data.name', '新分类');
$update = $this->actingAs($admin, 'api')->putJson('/tickets/'.$ticket->id, [
'status' => Ticket::StatusResolved,
'ticket_category_id' => $createdCategory->json('data.id'),
]);
$update
->assertOk()
->assertJsonPath('data.status', Ticket::StatusResolved);
$reply = $this->actingAs($admin, 'api')->postJson('/tickets/'.$ticket->id.'/messages', [
'content' => '已处理',
]);
$reply
->assertCreated()
->assertJsonPath('data.sender_type', 'admin');
$list = $this->actingAs($admin, 'api')->getJson('/tickets');
$list->assertOk();
$this->assertContains($ticket->id, collect($list->json('data.data'))->pluck('id')->all());
}
public function test_admin_can_manage_nested_ticket_categories(): void
{
$admin = $this->userWithPermissions(['platform.tickets.manage']);
$parent = TicketCategory::query()->create(['name' => '账号问题', 'is_active' => true]);
$created = $this->actingAs($admin, 'api')->postJson('/ticket-categories', [
'parent_id' => $parent->id,
'name' => '登录异常',
'description' => '登录相关问题',
'is_active' => true,
]);
$created
->assertCreated()
->assertJsonPath('data.parent_id', $parent->id)
->assertJsonMissingPath('data.sort_order');
$list = $this->actingAs($admin, 'api')->getJson('/ticket-categories');
$list->assertOk();
$parentNode = collect($list->json('tree'))->firstWhere('id', $parent->id);
$this->assertSame('账号问题', $parentNode['name']);
$this->assertSame('登录异常', $parentNode['children'][0]['name']);
}
public function test_user_without_ticket_permission_is_forbidden(): void
{
$user = User::factory()->create();
$response = $this->actingAs($user, 'api')->getJson('/tickets');
$response->assertStatus(403);
}
private function userWithPermissions(array $permissions): User
{
$user = User::factory()->create();
$role = Role::query()->create([
'name' => 'role-'.strtolower(str()->random(8)),
'guard_name' => 'api',
]);
foreach ($permissions as $permissionName) {
$permission = Permission::query()->firstOrCreate([
'name' => $permissionName,
'guard_name' => 'api',
]);
$role->givePermissionTo($permission);
}
$user->assignRole($role);
return $user;
}
}