83 lines
4.3 KiB
PHP
83 lines
4.3 KiB
PHP
<?php
|
|
|
|
use App\Enums\PurchasingRole;
|
|
use App\Models\Tenant;
|
|
use App\Models\User;
|
|
use App\Services\PublicNavigation;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Route;
|
|
use Inertia\Testing\AssertableInertia as Assert;
|
|
|
|
beforeEach(function () {
|
|
config(['public_navigation.enabled' => true]);
|
|
$this->withoutVite();
|
|
});
|
|
|
|
test('anonymous visitors enter the real dashboard without creating an authenticated identity', function () {
|
|
$this->get('/')->assertRedirect('/dashboard');
|
|
$this->get('/dashboard')->assertInertia(fn (Assert $p) => $p->component('dashboard')->where('auth.user', null)->where('company', null)->where('stats.total', 0)->where('publicNavigation.dataScope', 'none'));
|
|
$this->assertGuest('web');
|
|
expect(User::query()->count())->toBe(0);
|
|
});
|
|
|
|
test('all allowlisted real screens support direct anonymous navigation without business queries', function () {
|
|
$queries = [];
|
|
DB::listen(function ($query) use (&$queries) {
|
|
$queries[] = $query->sql;
|
|
});
|
|
$fixtures = [];
|
|
foreach (PublicNavigation::PAGES as $path => $component) {
|
|
$response = $this->get($path)->assertOk()->assertInertia(fn (Assert $p) => $p->component($component)->where('auth.user', null));
|
|
$fixtures[$component] = $response->original->getData()['page'];
|
|
$this->assertGuest('web');
|
|
}
|
|
expect($queries)->toBe([]);
|
|
file_put_contents(storage_path('app/private/public-navigation-fixtures.json'), json_encode($fixtures, JSON_THROW_ON_ERROR));
|
|
});
|
|
|
|
test('anonymous searches pagination and filters stay empty and never select either organisation', function () {
|
|
foreach (['Empresa reservada A', 'Empresa reservada B'] as $name) {
|
|
$tenant = Tenant::query()->create(['name' => $name]);
|
|
User::factory()->create(['tenant_id' => $tenant->id, 'name' => 'Nome confidencial']);
|
|
}
|
|
$this->get('/requisicoes?search=Empresa&page=2&status=pending')->assertInertia(fn (Assert $p) => $p->where('filters.search', 'Empresa')->where('requisitions.data', [])->where('requisitions.current_page', 2))->assertDontSee('Nome confidencial')->assertDontSee('Empresa reservada');
|
|
$this->get('/stock?search=Nome&warehouse_id=1')->assertInertia(fn (Assert $p) => $p->where('items', [])->where('filters.search', 'Nome'));
|
|
});
|
|
|
|
test('sensitive records access settings exports and every business write remain authenticated', function () {
|
|
foreach (['/pessoas/cadastro', '/pessoas/1', '/fornecedores/1/dados-bancarios', '/administracao/parametrizacao', '/relatorios', '/relatorios/compras.csv', '/settings/profile'] as $path) {
|
|
$this->get($path)->assertRedirect();
|
|
}
|
|
$this->get('/api/supplier-payables')->assertUnauthorized();
|
|
foreach (['/requisicoes', '/pessoas', '/stock/artigos', '/administracao/parametrizacao/tax'] as $path) {
|
|
$this->postJson($path, [])->assertUnauthorized();
|
|
}
|
|
});
|
|
|
|
test('authenticated sessions retain their original controllers and permissions and disabled mode remains private', function () {
|
|
$tenant = Tenant::query()->create(['name' => 'Empresa autenticada']);
|
|
$user = User::factory()->create(['tenant_id' => $tenant->id, 'purchasing_role' => PurchasingRole::Requester]);
|
|
$this->actingAs($user)->get('/dashboard')->assertInertia(fn (Assert $p) => $p->where('company.name', 'Empresa autenticada')->missing('publicNavigation'));
|
|
$this->get('/administracao/parametrizacao')->assertForbidden();
|
|
auth()->logout();
|
|
config(['public_navigation.enabled' => false]);
|
|
$this->get('/dashboard')->assertRedirect();
|
|
});
|
|
|
|
test('every authenticated mutation route remains inaccessible to an anonymous visitor', function () {
|
|
$checked = 0;
|
|
foreach (Route::getRoutes() as $route) {
|
|
if (! collect($route->gatherMiddleware())->contains(fn ($middleware) => $middleware === 'auth' || str_starts_with($middleware, 'auth:'))) {
|
|
continue;
|
|
}
|
|
$uri = '/'.preg_replace('/\{[^}]+\}/', '1', $route->uri());
|
|
foreach (array_intersect($route->methods(), ['POST', 'PUT', 'PATCH', 'DELETE']) as $method) {
|
|
$response = $this->json($method, $uri, []);
|
|
expect(in_array($response->status(), [401, 404], true))->toBeTrue($method.' '.$uri.' must remain protected');
|
|
$checked++;
|
|
}
|
|
}
|
|
expect($checked)->toBeGreaterThan(50);
|
|
$this->assertGuest('web');
|
|
});
|