+
@@ -73,7 +72,7 @@ const goBack = () => {
Apply for a Role
diff --git a/routes/web.php b/routes/web.php
index a5d4787..4bfa768 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -8,6 +8,7 @@
use App\Http\Controllers\ResourceController;
use App\Http\Controllers\ShortUrlController;
use App\Http\Controllers\SubjectController;
+use App\Http\Controllers\UserProfileController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
@@ -58,6 +59,7 @@
Route::get('/blogs', [BlogController::class, 'index']);
Route::get('/blogs/{blog}', [BlogController::class, 'show']);
+ Route::get('/u/{username}', [UserProfileController::class, 'show'])->name('user.profile');
Route::get('/', [SubjectController::class, 'index'])
->defaults('course', 'hsc')
diff --git a/tests/Feature/UserProfileTest.php b/tests/Feature/UserProfileTest.php
new file mode 100644
index 0000000..b2e5c91
--- /dev/null
+++ b/tests/Feature/UserProfileTest.php
@@ -0,0 +1,97 @@
+create([
+ 'name' => 'Tajim Ahmed',
+ 'username' => 'tajim_pro',
+ 'institution' => 'Notre Dame College',
+ 'about' => 'HSC 26 Candidate',
+ ]);
+
+ $response = $this->get('/u/tajim_pro');
+
+ $response->assertOk();
+ $response->assertInertia(fn ($page) => $page
+ ->component('User/Show')
+ ->where('profileUser.username', 'tajim_pro')
+ ->where('profileUser.name', 'Tajim Ahmed')
+ ->where('profileUser.institution', 'Notre Dame College')
+ );
+});
+
+test('viewing non-existent username renders 404 page', function () {
+ $response = $this->get('/u/non_existent_student_999');
+
+ $response->assertInertia(fn ($page) => $page->component('errors/404'));
+});
+
+test('public profile renders authored blogs when available', function () {
+ Role::create(['name' => 'editor']);
+
+ $user = User::factory()->create(['username' => 'contributor_john']);
+ $user->assignRole('editor');
+
+ Blog::create([
+ 'user_id' => $user->id,
+ 'title' => 'Calculus Masterclass',
+ 'slug' => 'calculus-masterclass',
+ 'content' => 'Sample guide',
+ 'is_published' => true,
+ ]);
+
+ $response = $this->get('/u/contributor_john');
+
+ $response->assertOk();
+ $response->assertInertia(fn ($page) => $page
+ ->component('User/Show')
+ ->where('profileUser.is_staff', true)
+ ->where('stats.blogsCount', 1)
+ ->has('blogs', 1)
+ ->where('blogs.0.title', 'Calculus Masterclass')
+ );
+});
+
+test('public profile accurately displays completed study topics and activities', function () {
+ $user = User::factory()->create(['username' => 'studious_student']);
+ $subject = Subject::create([
+ 'name' => 'Physics',
+ 'slug' => 'physics',
+ 'course' => 'hsc',
+ 'tailwind_format' => 'bg-indigo-500',
+ 'icon' => 'atom',
+ ]);
+ $node = Node::create([
+ 'subject_id' => $subject->id,
+ 'name' => 'Vector',
+ 'slug' => 'vector',
+ ]);
+ $resource = App\Models\Resource::create([
+ 'node_id' => $node->id,
+ 'title' => 'Vector Lecture Notes',
+ 'resource_type' => 'image',
+ 'file_path' => 'resources/vector.jpg',
+ ]);
+
+ ResourceCompletion::create([
+ 'user_id' => $user->id,
+ 'resource_id' => $resource->id,
+ ]);
+
+ $response = $this->get('/u/studious_student');
+
+ $response->assertOk();
+ $response->assertInertia(fn ($page) => $page
+ ->component('User/Show')
+ ->where('stats.completedResourcesCount', 1)
+ ->has('recentCompletions', 1)
+ ->where('recentCompletions.0.title', 'Vector Lecture Notes')
+ ->has('recentActivities.completions', 1)
+ );
+});