create(); $role = Role::firstOrCreate(['name' => 'ROLE_ADMIN'], ['color' => '#111111']); $admin->roles()->attach($role); return $admin; } it('lists attachment groups for admins', function (): void { $admin = makeAdminForAttachmentGroups(); AttachmentGroup::create(['name' => 'General', 'max_size_kb' => 10, 'is_active' => true]); Sanctum::actingAs($admin); $response = $this->getJson('/api/attachment-groups'); $response->assertOk(); $response->assertJsonFragment(['name' => 'General']); }); it('creates attachment groups as admin', function (): void { $admin = makeAdminForAttachmentGroups(); Sanctum::actingAs($admin); $response = $this->postJson('/api/attachment-groups', [ 'name' => 'Images', 'parent_id' => null, 'max_size_kb' => 1024, 'is_active' => true, ]); $response->assertStatus(201); $response->assertJsonFragment(['name' => 'Images']); }); it('updates attachment groups as admin', function (): void { $admin = makeAdminForAttachmentGroups(); $group = AttachmentGroup::create([ 'name' => 'Docs', 'parent_id' => null, 'position' => 1, 'max_size_kb' => 100, 'is_active' => true, ]); Sanctum::actingAs($admin); $response = $this->patchJson("/api/attachment-groups/{$group->id}", [ 'name' => 'Docs Updated', 'parent_id' => null, 'max_size_kb' => 200, 'is_active' => false, ]); $response->assertOk(); $response->assertJsonFragment(['name' => 'Docs Updated', 'is_active' => false]); }); it('prevents deleting groups with extensions or attachments', function (): void { $admin = makeAdminForAttachmentGroups(); $group = AttachmentGroup::create([ 'name' => 'Protected', 'max_size_kb' => 100, 'is_active' => true, ]); AttachmentExtension::create([ 'extension' => 'pdf', 'attachment_group_id' => $group->id, ]); Sanctum::actingAs($admin); $response = $this->deleteJson("/api/attachment-groups/{$group->id}"); $response->assertStatus(422); $response->assertJsonFragment(['message' => 'Attachment group has extensions.']); $group2 = AttachmentGroup::create([ 'name' => 'InUse', 'max_size_kb' => 100, 'is_active' => true, ]); Attachment::create([ 'thread_id' => null, 'post_id' => null, 'attachment_extension_id' => null, 'attachment_group_id' => $group2->id, 'user_id' => null, 'disk' => 'local', 'path' => 'attachments/misc/file.pdf', 'original_name' => 'file.pdf', 'extension' => 'pdf', 'mime_type' => 'application/pdf', 'size_bytes' => 10, ]); $response = $this->deleteJson("/api/attachment-groups/{$group2->id}"); $response->assertStatus(422); $response->assertJsonFragment(['message' => 'Attachment group is in use.']); }); it('reorders attachment groups', function (): void { $admin = makeAdminForAttachmentGroups(); $first = AttachmentGroup::create([ 'name' => 'First', 'position' => 1, 'max_size_kb' => 100, 'is_active' => true, ]); $second = AttachmentGroup::create([ 'name' => 'Second', 'position' => 2, 'max_size_kb' => 100, 'is_active' => true, ]); Sanctum::actingAs($admin); $response = $this->postJson('/api/attachment-groups/reorder', [ 'parentId' => null, 'orderedIds' => [$second->id, $first->id], ]); $response->assertOk(); $this->assertDatabaseHas('attachment_groups', [ 'id' => $second->id, 'position' => 1, ]); });