deleteRoutes() as $route) { $uri = $this->replaceAllPlaceholdersWithMissingId($route->uri()); $response = $this->requestAs($this->actorFor($route->uri()), 'DELETE', $uri); $this->assertStatusIn($response, [200, 202, 204, 302, 400, 401, 403, 404, 405, 409, 419, 422], "DELETE missing $uri"); $this->assertNoServerError($response, "DELETE missing $uri"); } } public function test_bulk_delete_style_routes_require_explicit_targets(): void { foreach ($this->bulkDestructiveRoutes() as $route) { $method = $this->primaryMethod($route); $uri = $route->uri(); $response = $this->requestAs($this->actorFor($uri), $method, $uri, [ 'ids' => [], 'confirm' => false, ]); $this->assertStatusIn($response, [200, 202, 204, 302, 400, 401, 403, 404, 405, 409, 419, 422], "$method $uri empty bulk destructive payload"); $this->assertNoServerError($response, "$method $uri empty bulk destructive payload"); if ($response->getStatusCode() >= 200 && $response->getStatusCode() < 300) { $this->assertTrue( in_array($response->getStatusCode(), [200, 202, 204], true), "$method $uri may succeed only as an explicit no-op, never by deleting an unspecified set." ); } } } public function test_archive_remove_cancel_and_void_routes_are_idempotent_or_conflict_safe(): void { foreach ($this->softDestructiveRoutes() as $route) { $method = $this->primaryMethod($route); $uri = $route->uri(); $first = $this->requestAs($this->actorFor($uri), $method, $uri, $this->payloadFor($method, $uri)); $second = $this->requestAs($this->actorFor($uri), $method, $uri, $this->payloadFor($method, $uri)); $this->assertControlled($first, $method, $uri); $this->assertControlled($second, $method, $uri); $this->assertNoServerError($first, "$method $uri first soft destructive attempt"); $this->assertNoServerError($second, "$method $uri second soft destructive attempt"); } } /** @return list */ private function deleteRoutes(): array { return array_slice(array_filter($this->apiRoutes(), fn (LaravelRoute $route): bool => $this->primaryMethod($route) === 'DELETE'), 0, 80); } /** @return list */ private function bulkDestructiveRoutes(): array { return array_slice(array_filter($this->apiRoutes(), function (LaravelRoute $route): bool { $uri = $route->uri(); return in_array($this->primaryMethod($route), ['POST', 'DELETE'], true) && preg_match('/bulk|batch|mass|selected|purge|delete/i', $uri) === 1; }), 0, 60); } /** @return list */ private function softDestructiveRoutes(): array { return array_slice(array_filter($this->apiRoutes(), function (LaravelRoute $route): bool { return preg_match('/archive|remove|cancel|void|resolve|close|reopen|restore/i', $route->uri()) === 1; }), 0, 80); } private function replaceAllPlaceholdersWithMissingId(string $uri): string { return preg_replace('/\{[^}]+\}/', '999999999', $uri) ?? $uri; } }