Challenge 3 — Solution Task: Write a store() method (like the chapter's example) that additionally validates the title is no longer than 200 characters, returning 422 with a specific error message if it is. Then write the matching cURL-based test code (Intermediate Chapter 7) that POSTs a JSON body to this endpoint and checks the response status code and decoded body. ---- src/Controllers/PostApiController.php (store method) ---- 'title and body are required'], 422); } if (strlen($input['title']) > 200) { jsonResponse(['error' => 'title must be 200 characters or fewer'], 422); } $post = new Post(getDbConnection()); $newId = $post->create($input['title'], $input['body']); jsonResponse(['id' => $newId], 201); } ?> ---- Matching cURL-based test code ---- str_repeat('a', 250), // deliberately too long, to test the validation 'body' => 'Some post content.' ]; $ch = curl_init("https://api.example.com/posts"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); $decoded = json_decode($response, true); if ($httpCode === 422 && $decoded['error'] === 'title must be 200 characters or fewer') { echo "Validation correctly rejected an over-long title."; } else { echo "Unexpected response: HTTP $httpCode - " . ($decoded['error'] ?? 'no error message'); } ?> Expected output: Validation correctly rejected an over-long title. Notes: - strlen($input['title']) > 200 is checked as a SEPARATE condition from the empty() check already in the chapter's own example - a title could be genuinely non-empty and still fail this new length rule, so both checks need to run independently rather than being combined into one condition. - The test deliberately sends a 250-character title (using str_repeat('a', 250) to generate it) specifically to exercise the new validation rule, rather than testing the already-covered empty- title case from the chapter's own original example. - Checking both $httpCode === 422 AND the specific error message text confirms not just that SOME validation failure occurred, but that it failed for the SPECIFIC reason being tested - a title genuinely missing entirely would also return 422, but with a different error message, so checking the message text distinguishes the two cases.