diff --git a/app/Services/WpPostService.php b/app/Services/WpPostService.php
index 6e463f1..85ec801 100644
--- a/app/Services/WpPostService.php
+++ b/app/Services/WpPostService.php
@@ -120,7 +120,9 @@ public static function getRelatedPosts(WpPost $post, int $limit = 3): Collection
?->slug;
if (! $categorySlug) {
- return collect();
+ // collect() builds a Support\Collection, which is not an
+ // Eloquent\Collection and fails this method's return type.
+ return new Collection;
}
return WpPost::query()
diff --git a/phpunit.xml b/phpunit.xml
index c09b5bc..61c031c 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -22,7 +22,8 @@
-
+
+
diff --git a/resources/js/components/PostCard.vue b/resources/js/components/PostCard.vue
index 9a10475..c467495 100644
--- a/resources/js/components/PostCard.vue
+++ b/resources/js/components/PostCard.vue
@@ -39,7 +39,11 @@ const getFormattedDate = (post: Post) => {
decoding="async"
/>
-
+
{{ post.categories[0].name }}
diff --git a/resources/js/components/PostContentCover.vue b/resources/js/components/PostContentCover.vue
index 47c0ba9..e882206 100644
--- a/resources/js/components/PostContentCover.vue
+++ b/resources/js/components/PostContentCover.vue
@@ -28,6 +28,7 @@ const { coverData } = defineProps<{
diff --git a/tests/Feature/RelatedPostsTest.php b/tests/Feature/RelatedPostsTest.php
new file mode 100644
index 0000000..8c48d27
--- /dev/null
+++ b/tests/Feature/RelatedPostsTest.php
@@ -0,0 +1,103 @@
+id('ID');
+ $table->unsignedBigInteger('post_author')->default(0);
+ $table->string('post_title');
+ $table->text('post_excerpt')->nullable();
+ $table->text('post_content')->nullable();
+ $table->string('post_name');
+ $table->string('post_type')->default('post');
+ $table->string('post_status')->default('publish');
+ $table->dateTime('post_date');
+ $table->string('guid')->default('');
+ });
+
+ Schema::create('wp_postmeta', function (Blueprint $table) {
+ $table->id('meta_id');
+ $table->unsignedBigInteger('post_id');
+ $table->string('meta_key');
+ $table->text('meta_value');
+ });
+
+ Schema::create('wp_terms', function (Blueprint $table) {
+ $table->id('term_id');
+ $table->string('name');
+ $table->string('slug');
+ });
+
+ Schema::create('wp_term_taxonomy', function (Blueprint $table) {
+ $table->id('term_taxonomy_id');
+ $table->unsignedBigInteger('term_id');
+ $table->string('taxonomy');
+ });
+
+ Schema::create('wp_term_relationships', function (Blueprint $table) {
+ $table->unsignedBigInteger('object_id');
+ $table->unsignedBigInteger('term_taxonomy_id');
+ });
+
+ cache()->flush();
+});
+
+function insertPost(int $id, string $slug): WpPost
+{
+ DB::table('wp_posts')->insert([
+ 'ID' => $id,
+ 'post_author' => 1,
+ 'post_title' => "Post {$id}",
+ 'post_name' => $slug,
+ 'post_type' => 'post',
+ 'post_status' => 'publish',
+ 'post_date' => '2026-07-01 10:00:00',
+ ]);
+
+ return WpPost::query()->findOrFail($id);
+}
+
+function attachCategory(int $postId, string $slug): void
+{
+ $termId = DB::table('wp_terms')->insertGetId(['name' => ucfirst($slug), 'slug' => $slug]);
+ $ttId = DB::table('wp_term_taxonomy')->insertGetId(['term_id' => $termId, 'taxonomy' => 'category']);
+ DB::table('wp_term_relationships')->insert(['object_id' => $postId, 'term_taxonomy_id' => $ttId]);
+}
+
+it('returns an Eloquent collection when the post has no category', function () {
+ $post = insertPost(1, 'sem-categoria');
+
+ $related = WpPostService::getRelatedPosts($post);
+
+ // The regression: collect() returns Support\Collection and blows up the
+ // declared Eloquent\Collection return type with a TypeError.
+ expect($related)->toBeInstanceOf(Collection::class)
+ ->and($related)->toBeEmpty();
+});
+
+it('still returns posts from the same category', function () {
+ $post = insertPost(1, 'principal');
+ attachCategory(1, 'games');
+
+ $sibling = insertPost(2, 'irmao');
+ DB::table('wp_term_relationships')->insert([
+ 'object_id' => 2,
+ 'term_taxonomy_id' => DB::table('wp_term_taxonomy')->value('term_taxonomy_id'),
+ ]);
+
+ $related = WpPostService::getRelatedPosts($post);
+
+ expect($related)->toBeInstanceOf(Collection::class)
+ ->and($related->pluck('ID')->all())->toBe([2])
+ ->and($related->pluck('ID')->all())->not->toContain(1);
+
+ unset($sibling);
+});