apiRoutes(), fn ($route) => $this->primaryMethod($route) === 'GET' && ! str_contains($route->uri(), '{')), 0, 120); foreach ($routes as $route) { $uri = $route->uri(); if ($this->isOpenApiDocumentRoute($uri)) { continue; } $response = $this->actingAs($this->actorFor($uri), 'api')->getJson($this->materializePath($uri)); $this->assertControlled($response, 'GET', $uri); $this->assertNoServerError($response, 'collection envelope '.$uri); if ($response->getStatusCode() !== 200 || ! $this->isJsonString($response->getContent())) { continue; } $payload = $response->json(); $this->assertTrue( is_array($payload) && (array_is_list($payload) || $payload !== []), $uri.' should keep a predictable collection/read envelope.' ); } } public function test_successful_detail_endpoints_keep_identifier_or_data_keys(): void { $routes = array_slice(array_filter($this->apiRoutes(), fn ($route) => $this->primaryMethod($route) === 'GET' && str_contains($route->uri(), '{')), 0, 100); foreach ($routes as $route) { $uri = $route->uri(); if ($this->isOpenApiDocumentRoute($uri)) { continue; } $response = $this->actingAs($this->actorFor($uri), 'api')->getJson($this->materializePath($uri)); $this->assertControlled($response, 'GET', $uri); $this->assertNoServerError($response, 'detail envelope '.$uri); if ($response->getStatusCode() !== 200 || ! $this->isJsonString($response->getContent())) { continue; } $payload = $response->json(); $this->assertTrue( is_array($payload) && (array_is_list($payload) || $payload !== []), $uri.' should keep an identifier, data wrapper, or explicit status/message contract.' ); } } private function isOpenApiDocumentRoute(string $uri): bool { return str_contains($uri, 'swagger.json') || str_contains($uri, 'openapi') || str_starts_with($uri, 'api/docs'); } }