Files
Investidor-V2/tests/Feature/DemographicInstallationTest.php
T

122 lines
7.5 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\User;
use App\Services\DemographicEvidence;
use App\Services\DemographicInstallation;
use App\Support\IsolatedQaDatabase;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Str;
use Tests\TestCase;
final class DemographicInstallationTest extends TestCase
{
use DatabaseTransactions;
private User $manager;
protected function setUp(): void
{
parent::setUp();
$this->withoutVite();
$this->assertTrue(IsolatedQaDatabase::allowsSchemaChanges());
$this->manager = User::factory()->create();
$this->manager->forceFill(['two_factor_secret' => Crypt::encrypt('JBSWY3DPEHPK3PXP'), 'two_factor_confirmed_at' => now()])->save();
$second = User::factory()->create();
// Test-only installation identities. This entire transaction is rolled back in QA.
if (DB::table('portal_superuser_pair')->where('id', 1)->exists()) {
DB::table('portal_superuser_pair')->where('id', 1)->update(['first_user_id' => $this->manager->id, 'second_user_id' => $second->id]);
}
config(['portal.managers' => [$this->manager->email]]);
}
public function test_installation_requires_fresh_session_mfa_even_for_a_designated_manager(): void
{
$this->actingAs($this->manager)->postJson('/management/demography/install', ['hash' => str_repeat('0', 64), 'operation_key' => (string) Str::uuid(), 'confirm' => true, 'reason' => 'Synthetic QA installation access test.'])->assertForbidden();
}
public function test_an_unauthorised_account_cannot_read_the_installation_plan(): void
{
$this->actingAs(User::factory()->create())->getJson('/management/demography/install')->assertForbidden();
}
public function test_an_unavailable_interpreter_blocks_the_plan_before_installation(): void
{
config(['demography.python' => base_path('storage/nonexistent-demography-python.exe')]);
$plan = app(DemographicInstallation::class)->preview($this->manager);
$this->assertFalse($plan['runtime_ready']);
$this->assertFalse($plan['ready']);
$this->assertStringContainsString('interpretador', $plan['notice']);
}
public function test_schema_flag_alone_does_not_authorise_the_operational_target(): void
{
$this->app['env'] = 'local';
config(['demography.authenticated_installation' => true, 'database.connections.pgsql.database' => 'investemoz', 'database.connections.pgsql.port' => '5432']);
$this->assertFalse(app(DemographicInstallation::class)->schemaAllowed());
}
public function test_stale_plan_is_rejected_before_schema_or_data_changes(): void
{
$this->actingAs($this->manager)->withSession(['portal.mfa_actor' => $this->manager->id, 'portal.mfa_at' => time()]);
$this->postJson('/management/demography/install', ['hash' => str_repeat('0', 64), 'operation_key' => (string) Str::uuid(), 'confirm' => true, 'reason' => 'Synthetic QA stale installation plan test.'])->assertConflict();
}
public function test_release_installs_imports_and_replays_on_the_restored_target(): void
{
if (getenv('DEMOGRAPHY_RELEASE_TESTS') !== '1') {
$this->markTestSkipped('Opt in only on the specifically restored demographic QA database with the real supplied Excel files and scanner.');
}
$this->assertMatchesRegularExpression('/^demography_restore_\d{8}_\d{6}_test$/', DB::connection()->getDatabaseName());
$this->assertFalse(Schema::hasTable('demographic_imports'));
$this->actingAs($this->manager)->withSession(['portal.mfa_actor' => $this->manager->id, 'portal.mfa_at' => time()]);
$service = app(DemographicInstallation::class);
$plan = $service->preview($this->manager);
$this->assertTrue($plan['ready']);
$input = ['hash' => $plan['hash'], 'operation_key' => (string) Str::uuid(), 'confirm' => true, 'reason' => 'Homologação da entrega numa cópia restaurada; apenas dados demográficos oficiais e identidades sintéticas QA.'];
$result = $service->apply($this->manager, $input);
$this->assertTrue($result['installed']);
$this->assertSame(154706, $result['record_count']);
$this->assertSame(154706, DB::table('demographic_observations')->count());
$this->assertSame(3, DB::table('demographic_imports')->where('status', 'approved')->count());
$repeat = $service->apply($this->manager, $input);
$this->assertTrue($repeat['repeated']);
$this->assertSame(154706, DB::table('demographic_observations')->count());
$districts = app(DemographicEvidence::class)->territories()->whereIn('name', ['Macate', 'Vanduzi'])->pluck('id')->all();
$this->assertCount(2, $districts);
$this->assertSame('available', app(DemographicEvidence::class)->analyse($districts, 2017, 2050, 'industry')['state']);
$this->assertDatabaseHas('audit_events', ['source_system' => 'demography-installation', 'actor_user_id' => $this->manager->id, 'correlation_id' => $input['operation_key']]);
$originals = DB::table('demographic_imports')->orderBy('id')->get()->toJson();
$originalIds = DB::table('demographic_imports')->pluck('id')->all();
$originalEvents = DB::table('demographic_events')->whereIn('import_id', $originalIds)->orderBy('id')->get()->toJson();
$plan = $service->preview($this->manager);
$this->assertSame('remaining', $plan['mode']);
$this->assertSame(8, $plan['pending_count']);
$this->assertCount(8, $plan['new_districts']);
$next = ['hash' => $plan['hash'], 'mode' => 'remaining', 'operation_key' => (string) Str::uuid(), 'confirm' => true, 'reason' => 'Oito províncias e oito distritos autorizados em13/11;QA restaurada sem alterações no activo.'];
$result = $service->apply($this->manager, $next);
$this->assertSame(639066, $result['record_count']);
$this->assertSame(793772, DB::table('demographic_observations')->count());
$this->assertSame(11, DB::table('demographic_imports')->where('status', 'approved')->count());
$this->assertSame($originals, DB::table('demographic_imports')->whereIn('id', $originalIds)->orderBy('id')->get()->toJson());
$this->assertSame($originalEvents, DB::table('demographic_events')->whereIn('import_id', $originalIds)->orderBy('id')->get()->toJson());
$this->assertTrue($service->apply($this->manager, $next)['repeated']);
$this->assertSame(793772, DB::table('demographic_observations')->count());
$this->assertSame('zambezia', $service->preview($this->manager)['mode']);
$this->assertSame(1, $service->preview($this->manager)['pending_count']);
$this->assertTrue($service->preview($this->manager)['ready']);
$this->assertCount(10, app(DemographicEvidence::class)->territories()->where('source_system', 'ine-demography')->get());
foreach (['Chongoene','Larde','Chimbonila','Doa','KaMphumu','Beira'] as $name) {
$literal = $name === 'KaMphumu' ? 'DISTRITO URBANO 1' : ($name === 'Beira' ? 'CIDADE DA BEIRA' : $name);
$territory = app(DemographicEvidence::class)->territories()->whereRaw('lower(name)=?', [mb_strtolower($literal)])->value('id');
$this->assertNotNull($territory, $name);
$this->assertSame('available', app(DemographicEvidence::class)->analyse([$territory],2017,2050,'general')['state']);
}
}
}