<?php

namespace Tests\Feature\Api\V1\FullSurface;

use Tests\Feature\Api\V1\FullSurface\Support\FullSurfaceE2EContractCase;

class ApiPolicyAuthorizationDiscoveryContractTest extends FullSurfaceE2EContractCase
{
    /** @test */
    public function protected_mutation_routes_are_not_publicly_mutable(): void
    {
        $routes = array_slice(array_filter($this->apiRoutes(), fn ($route) => in_array($this->primaryMethod($route), ['POST', 'PUT', 'PATCH', 'DELETE'], true)), 0, 140);

        foreach ($routes as $route) {
            $method = $this->primaryMethod($route);
            $uri = $route->uri();

            if (str_contains($uri, 'auth/login') || str_contains($uri, 'register') || str_contains($uri, 'contact')) {
                continue;
            }

            $response = $this->json($method, $this->materializePath($uri), $this->payloadFor($method, $uri));
            $this->assertStatusIn($response, [302, 400, 401, 403, 404, 405, 419, 422], "$method $uri should not be publicly mutable.");
        }
    }

    /** @test */
    public function permission_like_routes_reject_wildcards_from_non_admins(): void
    {
        $routes = $this->apiRoutesContainingAny(['permission', 'role', 'access', 'acl', 'authorization']);

        foreach ($routes as $route) {
            $method = $this->primaryMethod($route);
            $uri = $route->uri();

            if (! in_array($method, ['POST', 'PUT', 'PATCH'], true)) {
                continue;
            }

            $payload = $this->payloadFor($method, $uri) + [
                'permissions' => ['*', 'admin.*', 'finance.*'],
                'roles' => ['administrator'],
            ];

            $response = $this->requestAs($this->teacher, $method, $uri, $payload);
            $this->assertStatusIn($response, [401, 403, 404, 405, 409, 419, 422], "$method $uri should deny wildcard permission changes from teacher.");
        }
    }
}
