setAccessible(true); $parserProp->setValue( \Mockery::mock(\s9e\TextFormatter\Parser::class) ->shouldReceive('parse') ->andReturn('') ->getMock() ); $rendererProp = new ReflectionProperty(\App\Actions\BbcodeFormatter::class, 'renderer'); $rendererProp->setAccessible(true); $rendererProp->setValue( \Mockery::mock(\s9e\TextFormatter\Renderer::class) ->shouldReceive('render') ->andReturn('

') ->getMock() ); }); afterEach(function (): void { \Mockery::close(); }); it('parseIriId returns null for empty values and non numeric', function (): void { $controller = new ThreadController(); $ref = new ReflectionMethod($controller, 'parseIriId'); $ref->setAccessible(true); expect($ref->invoke($controller, null))->toBeNull(); expect($ref->invoke($controller, ''))->toBeNull(); expect($ref->invoke($controller, 'abc'))->toBeNull(); }); it('parseIriId parses forum iris and numeric values', function (): void { $controller = new ThreadController(); $ref = new ReflectionMethod($controller, 'parseIriId'); $ref->setAccessible(true); expect($ref->invoke($controller, '/api/forums/123'))->toBe(123); expect($ref->invoke($controller, '456'))->toBe(456); }); it('serializes thread with rank badge url when present', function (): void { Storage::fake('public'); $category = Forum::create([ 'name' => 'Category', 'description' => null, 'type' => 'category', 'parent_id' => null, 'position' => 1, ]); $forum = Forum::create([ 'name' => 'Forum', 'description' => null, 'type' => 'forum', 'parent_id' => $category->id, 'position' => 1, ]); $rank = \App\Models\Rank::create([ 'name' => 'Rank', 'badge_image_path' => 'ranks/badge.png', ]); $user = \App\Models\User::factory()->create([ 'rank_id' => $rank->id, ]); $thread = Thread::create([ 'forum_id' => $forum->id, 'user_id' => $user->id, 'title' => 'Thread', 'body' => 'Body', ]); $thread->load(['user.rank', 'attachments']); $controller = new ThreadController(); $ref = new ReflectionMethod($controller, 'serializeThread'); $ref->setAccessible(true); $payload = $ref->invoke($controller, $thread); expect($payload['user_rank_badge_url'])->not->toBeNull(); }); it('replaces attachment tags with inline image without thumb', function (): void { Setting::updateOrCreate(['key' => 'attachments.display_images_inline'], ['value' => 'true']); $category = Forum::create([ 'name' => 'Category', 'description' => null, 'type' => 'category', 'parent_id' => null, 'position' => 1, ]); $forum = Forum::create([ 'name' => 'Forum', 'description' => null, 'type' => 'forum', 'parent_id' => $category->id, 'position' => 1, ]); $thread = Thread::create([ 'forum_id' => $forum->id, 'user_id' => null, 'title' => 'Thread', 'body' => 'See [attachment]image.jpg[/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.'/image.jpg', 'original_name' => 'image.jpg', 'extension' => 'jpg', 'mime_type' => 'image/jpeg', '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('[img]'); }); it('defaults to inline images when setting is missing', function (): void { Setting::where('key', 'attachments.display_images_inline')->delete(); $controller = new ThreadController(); $ref = new ReflectionMethod($controller, 'displayImagesInline'); $ref->setAccessible(true); expect($ref->invoke($controller))->toBeTrue(); }); it('returns null group color when roles relation is null', function (): void { $controller = new ThreadController(); $user = \App\Models\User::factory()->create(); $user->setRelation('roles', null); $ref = new ReflectionMethod($controller, 'resolveGroupColor'); $ref->setAccessible(true); expect($ref->invoke($controller, $user))->toBeNull(); });