request('GET', '/api/students/' . self::STUDENT_ID . '/guardians', [ 'headers' => [ 'Host' => 'localhost', 'Accept' => 'application/json', ], ]); self::assertResponseStatusCodeSame(404); } /** * With a valid tenant but no JWT token, the endpoint returns 401. * Proves the endpoint exists and requires authentication. */ #[Test] public function getGuardiansReturns401WithoutAuthentication(): void { $client = static::createClient(); $client->request('GET', 'http://ecole-alpha.classeo.local/api/students/' . self::STUDENT_ID . '/guardians', [ 'headers' => [ 'Accept' => 'application/json', ], ]); self::assertResponseStatusCodeSame(401); } // ========================================================================= // POST /students/{studentId}/guardians — Security // ========================================================================= /** * Without a valid tenant subdomain, the endpoint returns 404. */ #[Test] public function linkGuardianReturns404WithoutTenant(): void { $client = static::createClient(); $client->request('POST', '/api/students/' . self::STUDENT_ID . '/guardians', [ 'headers' => [ 'Host' => 'localhost', 'Accept' => 'application/json', 'Content-Type' => 'application/json', ], 'json' => [ 'guardianId' => self::GUARDIAN_ID, 'relationshipType' => 'père', ], ]); self::assertResponseStatusCodeSame(404); } /** * With a valid tenant but no JWT token, the endpoint returns 401. */ #[Test] public function linkGuardianReturns401WithoutAuthentication(): void { $client = static::createClient(); $client->request('POST', 'http://ecole-alpha.classeo.local/api/students/' . self::STUDENT_ID . '/guardians', [ 'headers' => [ 'Accept' => 'application/json', 'Content-Type' => 'application/json', ], 'json' => [ 'guardianId' => self::GUARDIAN_ID, 'relationshipType' => 'père', ], ]); self::assertResponseStatusCodeSame(401); } // ========================================================================= // POST /students/{studentId}/guardians — Validation // ========================================================================= /** * Without tenant, validation never fires — returns 404 before reaching processor. */ #[Test] public function linkGuardianRejectsInvalidPayloadWithoutTenant(): void { $client = static::createClient(); $client->request('POST', '/api/students/' . self::STUDENT_ID . '/guardians', [ 'headers' => [ 'Host' => 'localhost', 'Accept' => 'application/json', 'Content-Type' => 'application/json', ], 'json' => [ 'guardianId' => '', 'relationshipType' => '', ], ]); // Without tenant → 404 (not 422) self::assertResponseStatusCodeSame(404); } // ========================================================================= // DELETE /students/{studentId}/guardians/{guardianId} — Security // ========================================================================= /** * Without a valid tenant subdomain, the endpoint returns 404. */ #[Test] public function unlinkGuardianReturns404WithoutTenant(): void { $client = static::createClient(); $client->request('DELETE', '/api/students/' . self::STUDENT_ID . '/guardians/' . self::GUARDIAN_ID, [ 'headers' => [ 'Host' => 'localhost', 'Accept' => 'application/json', ], ]); self::assertResponseStatusCodeSame(404); } /** * With a valid tenant but no JWT token, the endpoint returns 401. */ #[Test] public function unlinkGuardianReturns401WithoutAuthentication(): void { $client = static::createClient(); $client->request('DELETE', 'http://ecole-alpha.classeo.local/api/students/' . self::STUDENT_ID . '/guardians/' . self::GUARDIAN_ID, [ 'headers' => [ 'Accept' => 'application/json', ], ]); self::assertResponseStatusCodeSame(401); } // ========================================================================= // GET /me/children — Security // ========================================================================= /** * Without a valid tenant subdomain, the endpoint returns 404. */ #[Test] public function getMyChildrenReturns404WithoutTenant(): void { $client = static::createClient(); $client->request('GET', '/api/me/children', [ 'headers' => [ 'Host' => 'localhost', 'Accept' => 'application/json', ], ]); self::assertResponseStatusCodeSame(404); } /** * With a valid tenant but no JWT token, the endpoint returns 401. */ #[Test] public function getMyChildrenReturns401WithoutAuthentication(): void { $client = static::createClient(); $client->request('GET', 'http://ecole-alpha.classeo.local/api/me/children', [ 'headers' => [ 'Accept' => 'application/json', ], ]); self::assertResponseStatusCodeSame(401); } }