227 lines
6.9 KiB
PHP
227 lines
6.9 KiB
PHP
<?php
|
|
|
|
use App\Http\Controllers\ThreadController;
|
|
use App\Models\Attachment;
|
|
use App\Models\AttachmentGroup;
|
|
use App\Models\Forum;
|
|
use App\Models\Post;
|
|
use App\Models\Thread;
|
|
use App\Models\User;
|
|
use App\Models\Role;
|
|
use App\Models\Setting;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
function makeForumForThreadController(): Forum
|
|
{
|
|
$category = Forum::create([
|
|
'name' => 'Category',
|
|
'description' => null,
|
|
'type' => 'category',
|
|
'parent_id' => null,
|
|
'position' => 1,
|
|
]);
|
|
|
|
return Forum::create([
|
|
'name' => 'Forum',
|
|
'description' => null,
|
|
'type' => 'forum',
|
|
'parent_id' => $category->id,
|
|
'position' => 1,
|
|
]);
|
|
}
|
|
|
|
it('returns unauthorized for update when no user', function (): void {
|
|
$controller = new ThreadController();
|
|
$forum = makeForumForThreadController();
|
|
$thread = Thread::create([
|
|
'forum_id' => $forum->id,
|
|
'user_id' => null,
|
|
'title' => 'Thread',
|
|
'body' => 'Body',
|
|
]);
|
|
|
|
$request = Request::create("/api/threads/{$thread->id}", 'PATCH', [
|
|
'title' => 'New',
|
|
]);
|
|
$request->setUserResolver(fn () => null);
|
|
|
|
$response = $controller->update($request, $thread);
|
|
|
|
expect($response->getStatusCode())->toBe(401);
|
|
});
|
|
|
|
it('returns unauthorized for updateSolved when no user', function (): void {
|
|
$controller = new ThreadController();
|
|
$forum = makeForumForThreadController();
|
|
$thread = Thread::create([
|
|
'forum_id' => $forum->id,
|
|
'user_id' => null,
|
|
'title' => 'Thread',
|
|
'body' => 'Body',
|
|
]);
|
|
|
|
$request = Request::create("/api/threads/{$thread->id}/solved", 'PATCH', [
|
|
'solved' => true,
|
|
]);
|
|
$request->setUserResolver(fn () => null);
|
|
|
|
$response = $controller->updateSolved($request, $thread);
|
|
|
|
expect($response->getStatusCode())->toBe(401);
|
|
});
|
|
|
|
it('serializes threads with attachments, group colors, and inline images', function (): void {
|
|
Storage::fake('public');
|
|
|
|
$forum = makeForumForThreadController();
|
|
$role = Role::create(['name' => 'ROLE_HELPER', 'color' => '#ff0000']);
|
|
$user = User::factory()->create([
|
|
'avatar_path' => 'avatars/u.png',
|
|
'location' => 'Somewhere',
|
|
]);
|
|
$user->roles()->attach($role);
|
|
|
|
Setting::updateOrCreate(['key' => 'attachments.display_images_inline'], ['value' => '1']);
|
|
|
|
$thread = Thread::create([
|
|
'forum_id' => $forum->id,
|
|
'user_id' => $user->id,
|
|
'title' => 'Thread',
|
|
'body' => 'See [attachment]image.png[/attachment]',
|
|
]);
|
|
|
|
$post = Post::create([
|
|
'thread_id' => $thread->id,
|
|
'user_id' => $user->id,
|
|
'body' => 'Reply',
|
|
]);
|
|
|
|
$group = AttachmentGroup::create([
|
|
'name' => 'Images',
|
|
'max_size_kb' => 100,
|
|
'is_active' => true,
|
|
]);
|
|
|
|
$attachment = Attachment::create([
|
|
'thread_id' => $thread->id,
|
|
'post_id' => null,
|
|
'attachment_extension_id' => null,
|
|
'attachment_group_id' => $group->id,
|
|
'user_id' => $user->id,
|
|
'disk' => 'local',
|
|
'path' => 'attachments/threads/'.$thread->id.'/image.png',
|
|
'thumbnail_path' => 'attachments/threads/'.$thread->id.'/thumbs/image.png',
|
|
'original_name' => 'image.png',
|
|
'extension' => 'png',
|
|
'mime_type' => 'image/png',
|
|
'size_bytes' => 10,
|
|
]);
|
|
|
|
$thread->load(['user.roles', 'attachments.group', 'latestPost']);
|
|
|
|
$controller = new ThreadController();
|
|
$ref = new ReflectionMethod($controller, 'serializeThread');
|
|
$ref->setAccessible(true);
|
|
|
|
$payload = $ref->invoke($controller, $thread);
|
|
|
|
expect($payload['user_avatar_url'])->not->toBeNull();
|
|
expect($payload['user_group_color'])->toBe('#ff0000');
|
|
expect($payload['attachments'][0]['group']['name'])->toBe('Images');
|
|
expect($payload['attachments'][0]['thumbnail_url'])->toContain('/thumbnail');
|
|
expect($payload['body_html'])->toContain('<img');
|
|
expect($payload['last_post_id'])->toBe($post->id);
|
|
});
|
|
|
|
it('replaces attachment tags with links when inline images disabled', function (): void {
|
|
Setting::updateOrCreate(['key' => 'attachments.display_images_inline'], ['value' => '0']);
|
|
|
|
$forum = makeForumForThreadController();
|
|
$thread = Thread::create([
|
|
'forum_id' => $forum->id,
|
|
'user_id' => null,
|
|
'title' => 'Thread',
|
|
'body' => 'See [attachment]doc.pdf[/attachment]',
|
|
]);
|
|
|
|
$attachment = Attachment::create([
|
|
'thread_id' => $thread->id,
|
|
'post_id' => null,
|
|
'attachment_extension_id' => null,
|
|
'attachment_group_id' => null,
|
|
'user_id' => null,
|
|
'disk' => 'local',
|
|
'path' => 'attachments/threads/'.$thread->id.'/doc.pdf',
|
|
'original_name' => 'doc.pdf',
|
|
'extension' => 'pdf',
|
|
'mime_type' => 'application/pdf',
|
|
'size_bytes' => 10,
|
|
]);
|
|
|
|
$controller = new ThreadController();
|
|
$ref = new ReflectionMethod($controller, 'replaceAttachmentTags');
|
|
$ref->setAccessible(true);
|
|
|
|
$result = $ref->invoke($controller, $thread->body, collect([$attachment]));
|
|
|
|
expect($result)->toContain('[url=');
|
|
expect($result)->toContain('doc.pdf');
|
|
});
|
|
|
|
it('returns body unchanged when no attachments are present', function (): void {
|
|
$controller = new ThreadController();
|
|
$ref = new ReflectionMethod($controller, 'replaceAttachmentTags');
|
|
$ref->setAccessible(true);
|
|
|
|
$result = $ref->invoke($controller, 'No attachments', []);
|
|
|
|
expect($result)->toBe('No attachments');
|
|
});
|
|
|
|
it('returns original tag when attachment name does not match', function (): void {
|
|
$forum = makeForumForThreadController();
|
|
$thread = Thread::create([
|
|
'forum_id' => $forum->id,
|
|
'user_id' => null,
|
|
'title' => 'Thread',
|
|
'body' => 'See [attachment]missing.pdf[/attachment]',
|
|
]);
|
|
|
|
$attachment = Attachment::create([
|
|
'thread_id' => $thread->id,
|
|
'post_id' => null,
|
|
'attachment_extension_id' => null,
|
|
'attachment_group_id' => null,
|
|
'user_id' => null,
|
|
'disk' => 'local',
|
|
'path' => 'attachments/threads/'.$thread->id.'/doc.pdf',
|
|
'original_name' => 'doc.pdf',
|
|
'extension' => 'pdf',
|
|
'mime_type' => 'application/pdf',
|
|
'size_bytes' => 10,
|
|
]);
|
|
|
|
$controller = new ThreadController();
|
|
$ref = new ReflectionMethod($controller, 'replaceAttachmentTags');
|
|
$ref->setAccessible(true);
|
|
|
|
$result = $ref->invoke($controller, $thread->body, collect([$attachment]));
|
|
|
|
expect($result)->toContain('[attachment]missing.pdf[/attachment]');
|
|
});
|
|
|
|
it('returns body unchanged when attachment map is empty', function (): void {
|
|
$controller = new ThreadController();
|
|
$ref = new ReflectionMethod($controller, 'replaceAttachmentTags');
|
|
$ref->setAccessible(true);
|
|
|
|
$attachment = new Attachment([
|
|
'original_name' => '',
|
|
]);
|
|
|
|
$result = $ref->invoke($controller, 'Body', collect([$attachment]));
|
|
|
|
expect($result)->toBe('Body');
|
|
});
|