'sqlite::memory:', 'options' => [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, ], ]); set_database($memoryDatabase); (new MigrationManager($memoryDatabase, $tempMigrationPath))->runPending(); require_once __DIR__ . '/../database/seed_projects.php'; seed_projects(4, true); $router = new Router(); $app = new App(); require_once __DIR__ . '/../routes/web.php'; $dispatcher = new Dispatcher($router, $app); $home = $dispatcher->dispatch(new Request([], [], [ 'REQUEST_METHOD' => 'GET', 'REQUEST_URI' => '/', ])); if ($home->status() !== 200 || strpos($home->content(), 'Project Compass') === false) { echo "FAIL: dashboard did not render\n"; exit(1); } $projectsPage = $dispatcher->dispatch(new Request([], [], [ 'REQUEST_METHOD' => 'GET', 'REQUEST_URI' => '/projects', ])); if ($projectsPage->status() !== 200 || strpos($projectsPage->content(), 'Projects') === false) { echo "FAIL: projects list did not render\n"; exit(1); } $createPage = $dispatcher->dispatch(new Request([], [], [ 'REQUEST_METHOD' => 'GET', 'REQUEST_URI' => '/projects/create', ])); if ($createPage->status() !== 200 || strpos($createPage->content(), 'Create project') === false) { echo "FAIL: create project page did not render\n"; exit(1); } $projectPage = $dispatcher->dispatch(new Request([], [], [ 'REQUEST_METHOD' => 'GET', 'REQUEST_URI' => '/projects/1', ])); if ($projectPage->status() !== 200 || strpos($projectPage->content(), 'Kanban board') === false) { echo "FAIL: project board did not render\n"; exit(1); } $newProjectRequest = new Request([ '_token' => csrf_token(), ], [ '_token' => csrf_token(), 'name' => 'Orbit Mobile Relaunch', 'code' => '', 'client_name' => 'Orbit Labs', 'description' => 'A fresh mobile experience with project tracking and delivery visibility.', 'status' => 'planned', 'start_date' => '2026-05-09', 'due_date' => '2026-08-09', 'budget_cents' => '750000', 'owner_name' => 'Jordan Ellis', 'color_token' => 'emerald', 'members_text' => "Jordan Ellis\nRiley Kim", ], [ 'REQUEST_METHOD' => 'POST', 'REQUEST_URI' => '/projects', ]); $created = $dispatcher->dispatch($newProjectRequest); if ($created->status() !== 302) { echo "FAIL: project creation did not redirect\n"; exit(1); } $taskRequest = new Request([ '_token' => csrf_token(), ], [ '_token' => csrf_token(), 'title' => 'Design the intake flow', 'description' => 'Create a simple intake flow for requests and approvals.', 'priority' => 'high', 'status' => 'backlog', 'assignee' => 'Jordan Ellis', 'estimate_hours' => '10', 'due_date' => '2026-05-20', ], [ 'REQUEST_METHOD' => 'POST', 'REQUEST_URI' => '/projects/5/tasks', ]); $taskCreated = $dispatcher->dispatch($taskRequest); if ($taskCreated->status() !== 302) { echo "FAIL: task creation did not redirect\n"; exit(1); } $activity = $dispatcher->dispatch(new Request([], [], [ 'REQUEST_METHOD' => 'GET', 'REQUEST_URI' => '/activity', ])); if ($activity->status() !== 200 || strpos($activity->content(), 'Activity feed') === false) { echo "FAIL: activity feed did not render\n"; exit(1); } echo "PASS: project management app routes and data flow work\n";