Files
Investidor-V2/tests/Feature/InvestmentZoneAttachmentTest.php
nala 1106509116
tests / ci (push) Canceled after 0s
vrsao 2
2026-10-08 14:02:01 +02:00

130 lines
7.8 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\User;
use App\Services\Malware\MalwareScanner;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Tests\Support\CleanScannerFixture;
use Tests\TestCase;
class InvestmentZoneAttachmentTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
$this->app->bind(MalwareScanner::class, fn () => new CleanScannerFixture);
}
public function test_upload_is_private_until_administrative_review_and_explicit_public_selection(): void
{
Storage::fake('local');
$manager = $this->manager(true);
$zoneId = $this->draft($manager);
$response = $this->actingAs($manager)->post('/api/v2/investment/admin/zones/'.$zoneId.'/attachments', [
'file' => UploadedFile::fake()->createWithContent('decreto.pdf', "%PDF-1.7\nconteudo sintetico de ensaio\n"),
'kind' => 'legal_instrument', 'caption' => 'Diploma de ensaio', 'source_reference' => 'Arquivo oficial, referência sintética',
'source_date' => '2026-01-01', 'rights_status' => 'pending', 'rights_basis' => '',
], ['Accept' => 'application/json'])->assertCreated();
$attachment = $response->json();
$this->assertSame('pending', $attachment['review_status']);
$this->assertFalse($attachment['publicly_selected']);
$this->assertSame($manager->id, $attachment['uploaded_by']);
$document = DB::table('documents')->where('id', $attachment['document_id'])->first();
$this->assertSame('active', $document->status);
$this->assertSame('clean', $document->malware_scan_status);
$this->assertSame($document->sha256, $document->malware_scanned_sha256);
$this->assertSame('confidential', $document->data_classification);
$this->assertDatabaseHas('investment_zone_attachment_events', ['attachment_id' => $attachment['id'], 'action' => 'uploaded']);
$this->get('/zonas/'.$zoneId.'/anexos/'.$attachment['id'])->assertNotFound();
$this->actingAs($manager)->get('/management/investment/zones/'.$zoneId.'/attachments/'.$attachment['id'])->assertOk();
$this->actingAs($manager)->postJson('/api/v2/investment/admin/zone-attachments/'.$attachment['id'].'/review', [
'version_no' => 1, 'decision' => 'reviewed', 'rights_status' => 'confirmed', 'rights_basis' => 'Permissão documentada para o ensaio',
'personal_data_status' => 'none',
])->assertOk()->assertJsonPath('independent_review', false)->assertJsonPath('review_status', 'reviewed');
$this->assertDatabaseHas('investment_zone_attachment_events', ['attachment_id' => $attachment['id'], 'action' => 'review']);
$this->makeVisibleWithoutOperator($zoneId, $manager);
$this->actingAs($manager)->postJson('/api/v2/investment/admin/zone-attachments/'.$attachment['id'].'/select-public', ['version_no' => 2])->assertOk()->assertJsonPath('publicly_selected', true);
$this->getJson('/api/v2/investment/zones/'.$zoneId)->assertOk()
->assertJsonPath('attachments.0.caption', 'Diploma de ensaio')
->assertJsonMissingPath('attachments.0.uploaded_by')
->assertJsonMissingPath('attachments.0.rights_basis');
$this->get('/zonas/'.$zoneId.'/anexos/'.$attachment['id'])->assertOk();
$this->actingAs($manager)->postJson('/api/v2/investment/admin/zone-attachments/'.$attachment['id'].'/withdraw-public', ['version_no' => 3])->assertOk()->assertJsonPath('publicly_selected', false);
$this->get('/zonas/'.$zoneId.'/anexos/'.$attachment['id'])->assertNotFound();
}
public function test_public_selection_rejects_unknown_rights_or_personal_data_and_invalid_file_content(): void
{
Storage::fake('local');
$manager = $this->manager(true);
$zoneId = $this->draft($manager);
$this->actingAs($manager)->post('/api/v2/investment/admin/zones/'.$zoneId.'/attachments', [
'file' => UploadedFile::fake()->createWithContent('bad.pdf', 'not a PDF document'),
'kind' => 'study', 'caption' => 'Invalid test file', 'source_reference' => 'Synthetic test source', 'rights_status' => 'pending',
], ['Accept' => 'application/json'])->assertUnprocessable();
$this->actingAs($manager)->post('/api/v2/investment/admin/zones/'.$zoneId.'/attachments', [
'file' => UploadedFile::fake()->create('large.pdf', 20481, 'application/pdf'),
'kind' => 'study', 'caption' => 'Oversized test file', 'source_reference' => 'Synthetic test source', 'rights_status' => 'pending',
], ['Accept' => 'application/json'])->assertUnprocessable();
$attachment = $this->actingAs($manager)->post('/api/v2/investment/admin/zones/'.$zoneId.'/attachments', [
'file' => UploadedFile::fake()->createWithContent('study.pdf', "%PDF-1.7\nsynthetic test\n"),
'kind' => 'study', 'caption' => 'Study under review', 'source_reference' => 'Synthetic test source', 'rights_status' => 'pending',
], ['Accept' => 'application/json'])->assertCreated()->json();
$this->actingAs($manager)->postJson('/api/v2/investment/admin/zone-attachments/'.$attachment['id'].'/review', [
'version_no' => 1, 'decision' => 'reviewed', 'rights_status' => 'pending', 'personal_data_status' => 'unknown',
])->assertOk()->assertJsonPath('review_status', 'reviewed')->assertJsonPath('independent_review', false);
$this->makeVisibleWithoutOperator($zoneId, $manager);
$this->actingAs($manager)->postJson('/api/v2/investment/admin/zone-attachments/'.$attachment['id'].'/select-public', ['version_no' => 2])->assertUnprocessable();
$this->get('/zonas/'.$zoneId.'/anexos/'.$attachment['id'])->assertNotFound();
}
private function manager(bool $publisher): User
{
$user = User::factory()->create(['email_verified_at' => now()]);
$user->forceFill(['two_factor_secret' => Crypt::encryptString('synthetic-test-secret'), 'two_factor_confirmed_at' => now()])->save();
config(['portal.managers' => [...config('portal.managers', []), $user->email]]);
if ($publisher) {
config(['investment-zones.publishers' => [...config('investment-zones.publishers', []), $user->email]]);
}
return $user;
}
private function draft(User $manager): string
{
return $this->actingAs($manager)->postJson('/api/v2/investment/admin/zones', [
'code' => 'ATTACHMENT-TEST-'.Str::uuid(), 'category' => 'zee', 'physical_category' => 'economic_zone',
'legal_regime' => 'zee', 'name' => 'Zona de ensaio', 'description' => 'Descrição de ensaio para anexo.',
])->assertCreated()->json('id');
}
private function makeVisibleWithoutOperator(string $zoneId, User $editor): void
{
$reviewer = $this->manager(false);
$sourceId = (string) Str::uuid();
DB::table('investment_legal_sources')->insert([
'id' => $sourceId, 'title' => 'Fonte de ensaio', 'url' => 'https://example.test/zone-source', 'diploma' => 'Documento sintético',
'article' => 'Artigo de ensaio', 'competent_entity' => 'Entidade sintética', 'valid_from' => today()->toDateString(),
'validation_status' => 'validated', 'owner_id' => $editor->id, 'validator_id' => $reviewer->id,
'validated_at' => now(), 'version_no' => 1, 'created_at' => now(), 'updated_at' => now(),
]);
DB::table('investment_zones')->where('id', $zoneId)->update([
'legal_source_id' => $sourceId, 'publication_status' => 'published', 'validation_status' => 'validated',
'reviewer_id' => $reviewer->id, 'published_at' => now(), 'version_no' => 2,
]);
}
}