113 lines
8.0 KiB
PHP
113 lines
8.0 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\User;
|
|
use App\Services\VirtualDesk;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Crypt;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Http;
|
|
use Illuminate\Support\Str;
|
|
use Inertia\Testing\AssertableInertia as Assert;
|
|
use Tests\TestCase;
|
|
|
|
class PortalAuditConsumerLotTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
$this->withoutVite();
|
|
Http::fake();
|
|
config(['suitecrm.enabled' => false, 'investmoz_ai.enabled' => false, 'crm.notifications.enabled' => false]);
|
|
$this->assertSame(55441, (int) DB::selectOne('SELECT inet_server_port() AS port')->port);
|
|
}
|
|
|
|
private function manager(): User
|
|
{
|
|
$actor = User::factory()->create();
|
|
$actor->forceFill(['two_factor_secret' => Crypt::encryptString('QA-ONLY'), 'two_factor_confirmed_at' => now()])->save();
|
|
config(['portal.managers' => [$actor->email]]);
|
|
|
|
return $actor;
|
|
}
|
|
|
|
private function location(string $type, ?string $parent = null): string
|
|
{
|
|
$id = (string) Str::uuid();
|
|
DB::table('geo_locations')->insert(['id' => $id, 'name' => 'Synthetic '.$type, 'code' => $id, 'location_type' => $type, 'parent_id' => $parent,
|
|
'source_system' => 'cartografia-workbook', 'external_id' => '964a187ad32ea553b9e112cd159caa90b900050c42b7329594a75bcd798a96ff:'.$id, 'data_classification' => 'public']);
|
|
|
|
return $id;
|
|
}
|
|
|
|
public function test_private_official_context_is_authorized_and_does_not_become_a_public_investment_site(): void
|
|
{
|
|
$manager = $this->manager();
|
|
$province = $this->location('province', $this->location('country'));
|
|
$district = $this->location('district', $province);
|
|
$post = $this->location('admin_post', $district);
|
|
$locality = $this->location('locality', $post);
|
|
$id = (string) Str::uuid();
|
|
$properties = json_encode(['purpose' => 'administrative_boundary', 'authority' => 'Synthetic official fixture, QA only', 'source_version' => '2019-06-07', 'legal_currentness' => 'not_determined', 'source_sha256' => str_repeat('a', 64)]);
|
|
DB::insert("INSERT INTO geo_geometries(id,geo_location_id,geometry_type,geom,properties,data_classification) VALUES (?,?,'polygon',ST_GeomFromText('POLYGON((32 -20,33 -20,33 -19,32 -19,32 -20))',4326),?::jsonb,'internal')", [$id, $post, $properties]);
|
|
$url = '/api/v1/investment/territory-geometries?territory_id='.$locality;
|
|
$this->getJson($url)->assertOk()->assertJsonPath('territory_registered', true)->assertJsonPath('selected_geometry_available', false)->assertJsonCount(0, 'areas');
|
|
$private = '/management/territory-geometries?territory_id='.$locality;
|
|
$this->actingAs(User::factory()->create())->getJson($private)->assertForbidden();
|
|
$this->actingAs($manager)->getJson($private)->assertOk()->assertJsonPath('selected_geometry_available', false)->assertJsonPath('context_geometry_count', 1)
|
|
->assertJsonPath('areas.0.territory_id', $post)->assertJsonPath('areas.0.source_date', '2019-06-07')->assertJsonPath('areas.0.geometry.type', 'Polygon')->assertJsonPath('investment_site', false);
|
|
$this->getJson('/management/territory-geometries?territory_id='.$post)->assertJsonPath('selected_geometry_available', true);
|
|
$this->getJson('/management/territory-geometries?territory_id=bad')->assertUnprocessable();
|
|
DB::table('geo_geometries')->where('id', $id)->update(['data_classification' => 'public']); // explicit synthetic QA permission, never production
|
|
$this->getJson($url)->assertJsonPath('context_geometry_count', 1)->assertJsonPath('selected_geometry_available', false);
|
|
DB::table('geo_geometries')->where('id', $id)->update(['deleted_at' => now()]);
|
|
$this->getJson($private)->assertJsonCount(0, 'areas');
|
|
$this->assertDatabaseCount('opportunity_locations', 0);
|
|
$this->assertDatabaseCount('investment_zone_geometries', 0);
|
|
}
|
|
|
|
public function test_all_three_desk_forms_save_recover_countries_and_support_authorized_corrections(): void
|
|
{
|
|
$manager = $this->manager();
|
|
$owner = User::factory()->create();
|
|
foreach (['project-preparation', 'project-change', 'project-follow-up'] as $index => $code) {
|
|
$service = $this->actingAs($manager)->postJson('/management/balcao/servicos', ['code' => $code, 'confirm' => true])->assertCreated()->json('id');
|
|
$case = $this->actingAs($owner)->postJson('/balcao-virtual/dossiers', ['title' => 'Synthetic QA '.$code, 'client_key' => (string) Str::uuid(), 'reuse_consent' => true])->assertCreated()->json('id');
|
|
$id = $this->postJson('/balcao-virtual/dossiers/'.$case.'/pedidos', ['service_version_id' => $service, 'client_key' => (string) Str::uuid()])->assertCreated()->json('id');
|
|
$url = '/balcao-virtual/pedidos/'.$id;
|
|
$payload = ['title' => 'Synthetic QA', 'description' => 'Synthetic description', 'country' => 'PT', 'declared_origin_country_code' => 'ZA'];
|
|
if ($code === 'project-preparation') {
|
|
$payload += ['investment_amount' => '10.00', 'currency' => 'MZN'];
|
|
}
|
|
if ($code === 'project-change') {
|
|
$payload += ['original_reference' => 'QA-only', 'change_reason' => 'Synthetic change'];
|
|
}
|
|
if ($code === 'project-follow-up') {
|
|
$payload += ['original_reference' => 'QA-only', 'progress' => 'Synthetic progress'];
|
|
}
|
|
$this->putJson($url, ['version' => 1, 'payload' => [...$payload, 'country' => 'ZZ']])->assertUnprocessable()->assertJsonValidationErrors('payload.country');
|
|
$this->putJson($url, ['version' => 1, 'payload' => $payload])->assertOk()->assertJsonPath('version', 2);
|
|
$this->get($url)->assertInertia(fn (Assert $p) => $p->has('countries', 249)->where('request.payload.country', 'PT')->where('request.payload.declared_origin_country_code', 'ZA'));
|
|
$cipher = DB::table('desk_requests')->where('id', $id)->value('payload');
|
|
$this->assertSame('PT', app(VirtualDesk::class)->decode($cipher)['country']);
|
|
$this->putJson($url, ['version' => 2, 'payload' => $payload, 'submit' => true, 'consent' => true])->assertOk()->assertJsonPath('status', 'submitted');
|
|
$this->postJson($url.'/estado', ['version' => 3, 'status' => 'reviewing', 'reason' => 'Synthetic self review'])->assertForbidden();
|
|
$this->actingAs($manager)->postJson($url.'/estado', ['version' => 3, 'status' => 'returned', 'reason' => 'Synthetic authorized correction', 'editable_fields' => ['country', 'declared_origin_country_code']])->assertOk()->assertJsonPath('version', 4);
|
|
$this->actingAs($owner)->putJson($url, ['version' => 4, 'payload' => [...$payload, 'title' => 'Unauthorized change']])->assertUnprocessable();
|
|
$this->putJson($url, ['version' => 4, 'payload' => [...$payload, 'country' => 'MZ', 'declared_origin_country_code' => 'PT']])->assertOk()->assertJsonPath('version', 5);
|
|
$this->getJson($url)->assertJsonPath('request.payload.country', 'MZ')->assertJsonPath('request.payload.declared_origin_country_code', 'PT');
|
|
$this->putJson($url, ['version' => 4, 'payload' => $payload])->assertConflict();
|
|
$this->actingAs(User::factory()->create())->getJson($url)->assertForbidden();
|
|
$this->assertDatabaseHas('desk_requests', ['id' => $id, 'version' => 5, 'status' => 'returned']);
|
|
$this->actingAs($manager)->get('/management/interests?origin=PT')->assertInertia(fn (Assert $p) => $p
|
|
->where('originStatistics.desk.0.code', 'PT')->where('originStatistics.desk.0.count', $index + 1)
|
|
->has('originStatistics.interests', 0)->has('originStatistics.businesses', 0));
|
|
$this->get('/management/interests?origin=ZA')->assertInertia(fn (Assert $p) => $p->has('originStatistics.desk', 0));
|
|
}
|
|
Http::assertNothingSent();
|
|
}
|
|
}
|