Files
Investidor-V2/tests/Feature/ExistingBusinessFoundationTest.php
T
nala e65cb26901
tests / ci (push) Canceled after 0s
varias alteracoes
2026-10-06 14:50:12 +02:00

107 lines
4.9 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\ExistingBusiness;
use App\Models\User;
use App\Services\ExistingBusinessDrafts;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\QueryException;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Tests\TestCase;
class ExistingBusinessFoundationTest extends TestCase
{
use RefreshDatabase;
/** @return array<string,mixed> */
private function draft(): array
{
return ['modality' => 'company_sale', 'classification' => 'confidential', 'reason' => 'Synthetic draft created', 'payload' => ['title' => 'Private synthetic business']];
}
public function test_draft_is_encrypted_and_history_is_versioned_with_stale_writes_rejected(): void
{
$owner = User::factory()->create();
$service = app(ExistingBusinessDrafts::class);
$business = $service->save($owner, $this->draft());
$this->assertSame('draft', $business->status);
$this->assertArrayNotHasKey('payload', $business->toArray());
$raw = DB::table('existing_businesses')->where('id', $business->id)->value('payload');
$this->assertStringNotContainsString('Private synthetic', $raw);
$this->assertStringContainsString('Private synthetic', Crypt::decryptString($raw));
$service->save($owner, [...$this->draft(), 'version_no' => 1], $business->id);
$this->assertDatabaseCount('existing_business_revisions', 2);
try {
$service->save($owner, [...$this->draft(), 'version_no' => 1], $business->id);
$this->fail('Stale update accepted');
} catch (HttpException $e) {
$this->assertSame(409, $e->getStatusCode());
}
$this->assertDatabaseCount('existing_business_revisions', 2);
$service->archive($owner, $business->id, 2, 'Synthetic archive reason');
$this->assertNull(ExistingBusiness::find($business->id));
$this->assertSame(3, ExistingBusiness::withTrashed()->findOrFail($business->id)->version_no);
$this->assertDatabaseCount('existing_business_revisions', 3);
}
public function test_other_user_including_manager_cannot_edit_reserved_business(): void
{
$service = app(ExistingBusinessDrafts::class);
$business = $service->save(User::factory()->create(), $this->draft());
$other = User::factory()->create();
config(['portal.managers' => [$other->email]]);
$this->expectException(AuthorizationException::class);
$service->save($other, [...$this->draft(), 'version_no' => 1], $business->id);
}
public function test_unverified_account_cannot_create_business(): void
{
$this->expectException(AuthorizationException::class);
app(ExistingBusinessDrafts::class)->save(User::factory()->unverified()->create(), $this->draft());
}
public function test_database_prevents_publication_and_history_changes(): void
{
$business = app(ExistingBusinessDrafts::class)->save(User::factory()->create(), $this->draft());
foreach (['publish', 'history'] as $operation) {
DB::statement('SAVEPOINT business_constraint');
try {
if ($operation === 'publish') {
DB::table('existing_businesses')->where('id', $business->id)->update(['status' => 'published']);
} else {
DB::table('existing_business_revisions')->where('business_id', $business->id)->delete();
}
$this->fail('Database invariant was not enforced');
} catch (QueryException) {
DB::statement('ROLLBACK TO SAVEPOINT business_constraint');
$this->assertTrue(true);
}
}
$this->assertDatabaseCount('existing_business_revisions', 1);
}
public function test_empty_rollback_is_reversible_and_populated_rollback_is_refused(): void
{
$migration = require database_path('migrations/2026_09_28_130000_existing_business_foundation.php');
$intake = require database_path('migrations/2026_09_28_140000_existing_business_intake.php');
$marketplace = require database_path('migrations/2026_09_30_120000_extend_existing_business_marketplace.php');
$draftContinuity = require database_path('migrations/2026_10_04_120000_add_simulation_draft_continuity.php');
$draftContinuity->down();
$marketplace->down();
$intake->down();
$migration->down();
$migration->up();
$intake->up();
$marketplace->up();
$draftContinuity->up();
app(ExistingBusinessDrafts::class)->save(User::factory()->create(), $this->draft());
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('destructive rollback refused');
$migration->down();
}
}