103 lines
6.7 KiB
PHP
103 lines
6.7 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Jobs\ScanDocumentForMalware;
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
|
use Illuminate\Http\UploadedFile;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Queue;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Support\Str;
|
|
use Tests\TestCase;
|
|
|
|
final class IvaOfferWorkflowDraftTest extends TestCase
|
|
{
|
|
use DatabaseTransactions;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
$output = base_path('outputs/iva-l1-returnees-20261025');
|
|
if (! is_dir($output)) {
|
|
mkdir($output, 0775, true);
|
|
}
|
|
}
|
|
|
|
public function test_p104_operational_selection_recovers_without_recalculating_history(): void
|
|
{
|
|
$target = DB::selectOne('select current_database() as name,inet_server_port() as port');
|
|
$this->assertSame('simulator_fiscal_delta_20261021_test', $target->name);
|
|
$this->assertSame(55441, (int) $target->port);
|
|
config(['investor-path.enabled' => true, 'suitecrm.enabled' => false]);
|
|
$this->actingAs(User::factory()->create(['email_verified_at' => now()]));
|
|
$draft = json_decode(file_get_contents(base_path('tests/frontend/fixtures/iva-fx-selection.json')), true, flags: JSON_THROW_ON_ERROR);
|
|
$id = $this->postJson('/api/v1/simulation-drafts', ['personal_snapshot' => [], 'economic_snapshot' => $draft], ['Idempotency-Key' => (string) Str::uuid()])->assertCreated()->json('data.id');
|
|
$recovered = $this->getJson('/api/v1/simulation-drafts/'.$id)->assertOk()->json('data.economic_snapshot');
|
|
$this->assertSame($draft['modelo_a_snapshot'], $recovered['modelo_a_snapshot']);
|
|
$s = json_decode($recovered['modelo_a_snapshot'], true, flags: JSON_THROW_ON_ERROR);
|
|
$b = $s['currencyEvents']['opportunity:365'];
|
|
$this->assertCount(1, $b['history']);
|
|
$this->assertSame('6406.9775', $b['history'][0]['rows'][0]['scenarioAmount']);
|
|
$this->assertSame('12782.00', $b['result']['rows'][0]['scenarioAmount']);
|
|
$this->assertSame('mean', $b['rows'][0]['fxSelection']['applied']['column']);
|
|
$this->assertNull($b['result']['rows'][0]['baseAmount']);
|
|
$this->assertNull($b['result']['rows'][0]['vat']);
|
|
$prior = json_decode(json_decode(file_get_contents(base_path('tests/frontend/fixtures/iva-offer-workflow.json')), true)['modelo_a_snapshot'], true);
|
|
$this->assertSame(array_diff_key($prior, ['currencyEvents' => true]), array_diff_key($s, ['currencyEvents' => true]));
|
|
foreach ($prior['currencyEvents'] as $k => $v) {
|
|
$this->assertSame($v, $s['currencyEvents'][$k]);
|
|
}
|
|
file_put_contents(base_path('outputs/iva-l1-returnees-20261025/fx-recovered.json'), json_encode($recovered, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE));
|
|
}
|
|
|
|
public function test_private_decision_attachment_and_recovery_preserve_prior_books(): void
|
|
{
|
|
$target = DB::selectOne('select current_database() as name,inet_server_port() as port');
|
|
$this->assertSame('simulator_fiscal_delta_20261021_test', $target->name);
|
|
$this->assertSame(55441, (int) $target->port);
|
|
config(['investor-path.enabled' => true, 'suitecrm.enabled' => false]);
|
|
Queue::fake();
|
|
Storage::fake('local');
|
|
$owner = User::factory()->create(['email_verified_at' => now()]);
|
|
$this->actingAs($owner);
|
|
$draft = json_decode(file_get_contents(base_path('tests/frontend/fixtures/iva-offer-workflow.json')), true, flags: JSON_THROW_ON_ERROR);
|
|
$id = $this->postJson('/api/v1/simulation-drafts', ['personal_snapshot' => [], 'economic_snapshot' => $draft], ['Idempotency-Key' => (string) Str::uuid()])->assertCreated()->json('data.id');
|
|
$file = UploadedFile::fake()->createWithContent('SYNTHETIC-QA-despacho.txt', 'SYNTHETIC QA despacho privado para teste de continuidade.');
|
|
$url = '/api/v1/simulation-drafts/'.$id.'/offer-documents';
|
|
$doc = $this->post($url, ['file' => $file], ['Accept' => 'application/json'])->assertCreated()->json('data');
|
|
$this->assertSame(hash('sha256', 'SYNTHETIC QA despacho privado para teste de continuidade.'), $doc['sha256']);
|
|
Queue::assertPushed(ScanDocumentForMalware::class);
|
|
$this->post($url, ['file' => UploadedFile::fake()->createWithContent('copy.txt', 'SYNTHETIC QA despacho privado para teste de continuidade.')], ['Accept' => 'application/json'])->assertOk()->assertJsonPath('data.id', $doc['id']);
|
|
$this->getJson($doc['url'])->assertStatus(409);
|
|
$this->getJson($url)->assertOk()->assertJsonCount(1, 'data');
|
|
$this->actingAs(User::factory()->create(['email_verified_at' => now()]));
|
|
$this->getJson($doc['url'])->assertNotFound();
|
|
$this->getJson($url)->assertNotFound();
|
|
$this->post($url, ['file' => UploadedFile::fake()->createWithContent('other.txt', 'SYNTHETIC QA other')], ['Accept' => 'application/json'])->assertNotFound();
|
|
$this->actingAs($owner);
|
|
DB::table('documents')->where('id', $doc['id'])->update(['status' => 'active', 'malware_scan_status' => 'clean', 'malware_scanned_sha256' => $doc['sha256']]);
|
|
$this->get($doc['url'])->assertOk()->assertHeader('X-Content-Type-Options', 'nosniff');
|
|
$recovered = $this->getJson('/api/v1/simulation-drafts/'.$id)->assertOk()->json('data.economic_snapshot');
|
|
$this->assertSame($draft['modelo_a_snapshot'], $recovered['modelo_a_snapshot']);
|
|
$snapshot = json_decode($recovered['modelo_a_snapshot'], true, flags: JSON_THROW_ON_ERROR);
|
|
$this->assertCount(2, $snapshot['offerPreparations']['opportunity:364']['rows']);
|
|
$prior = json_decode(json_decode(file_get_contents(base_path('tests/frontend/fixtures/iva-returnees.json')), true)['modelo_a_snapshot'], true);
|
|
$this->assertSame(array_diff_key($prior, ['offerPreparations' => true]), array_diff_key($snapshot, ['offerPreparations' => true]));
|
|
foreach ($prior['offerPreparations'] as $k => $v) {
|
|
$this->assertSame($v, $snapshot['offerPreparations'][$k]);
|
|
}
|
|
// The UI seed contains the real uploaded private decision identity, not a synthetic URL passed as an upload.
|
|
foreach ($snapshot['offerPreparations']['opportunity:364']['rows'] as &$row) {
|
|
$row['workflow']['decisionAttachment'] = $doc;
|
|
}
|
|
unset($row);
|
|
$recovered['modelo_a_snapshot'] = json_encode($snapshot, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE);
|
|
file_put_contents(base_path('outputs/iva-l1-returnees-20261025/recovered.json'), json_encode($recovered, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE));
|
|
$stored = DB::table('documents')->where('id', $doc['id'])->first();
|
|
Storage::disk('local')->put($stored->storage_key, 'changed');
|
|
$this->getJson($doc['url'])->assertStatus(409);
|
|
}
|
|
}
|