90 lines
5.3 KiB
PHP
90 lines
5.3 KiB
PHP
<?php
|
|
|
|
use App\Models\User;
|
|
use App\Services\ExternalPaymentWorkflow;
|
|
use App\Services\SupplierPayables;
|
|
use Illuminate\Database\QueryException;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Str;
|
|
use Symfony\Component\HttpKernel\Exception\HttpException;
|
|
use Tempo\Finance\Payables\PayablesSchema;
|
|
|
|
require_once __DIR__.'/../Support/PaymentFixture.php';
|
|
|
|
beforeEach(function () {
|
|
$this->f = paymentFixture();
|
|
config(['common-payables.enabled' => true, 'common-payables.source_instance' => 'integration-fixture-instance']);
|
|
foreach ([$this->f['author'], $this->f['validator']] as $user) {
|
|
foreach (['view', 'prepare', 'validate'] as $action) {
|
|
DB::table('pa_access')->insert(['tenant_id' => $user->tenant_id, 'company_id' => 0, 'unit_id' => 0,
|
|
'user_id' => $user->id, 'person' => 'fixture-person-'.$user->id, 'action' => $action]);
|
|
}
|
|
}
|
|
$this->actingAs($this->f['author']);
|
|
});
|
|
|
|
test('explicit activation recognises a confirmed invoice once on the normal application schema', function () {
|
|
expect(SupplierPayables::enabled())->toBeTrue();
|
|
$service = app(SupplierPayables::class);
|
|
$prepared = $service->engine($this->f['author'])->command('prepare', $this->f['invoice']->id, 'Conferência de integração sintética', (string) Str::uuid());
|
|
expect($prepared['state'])->toBe('prepared');
|
|
$this->actingAs($this->f['validator']);
|
|
$recognised = $service->engine($this->f['validator'])->command('validate', $prepared['proposal_id'], 'Validação independente de teste', (string) Str::uuid());
|
|
expect($recognised['state'])->toBe('recognised');
|
|
$service->engine($this->f['validator'])->command('validate', $prepared['proposal_id'], 'Validação repetida de teste', (string) Str::uuid());
|
|
expect(DB::table('pa_obligations')->count())->toBe(1)
|
|
->and(DB::table('pa_obligations')->value('principal_minor'))->toBe(6000)
|
|
->and(DB::table('pa_obligations')->value('due_on'))->toBeNull()
|
|
->and(app(ExternalPaymentWorkflow::class)->outstanding($this->f['invoice']))->toBe(6000);
|
|
$this->getJson('/api/supplier-payables?invoice='.$this->f['invoice']->id)->assertOk()->assertJsonCount(1, 'obligations');
|
|
config(['common-payables.source_instance' => 'different-installation']);
|
|
expect(fn () => $service->principal($this->f['invoice']))->toThrow(HttpException::class);
|
|
});
|
|
|
|
test('legacy payments keep their balance and prevent automatic import of a second debt', function () {
|
|
$payments = app(ExternalPaymentWorkflow::class);
|
|
$payment = $payments->register($this->f['author'], $this->f['invoice'], $this->f['payment_data']);
|
|
$this->actingAs($this->f['validator']);
|
|
$payments->review($this->f['validator'], $payment, 'confirmed', 'Conferência sintética do histórico');
|
|
expect($payments->outstanding($this->f['invoice']))->toBe(2000);
|
|
$this->actingAs($this->f['author']);
|
|
$prepared = app(SupplierPayables::class)->engine($this->f['author'])->command('prepare', $this->f['invoice']->id, 'Tentativa com pagamento anterior', (string) Str::uuid());
|
|
expect($prepared['state'])->toBe('pending_source');
|
|
$this->actingAs($this->f['validator']);
|
|
$result = app(SupplierPayables::class)->engine($this->f['validator'])->command('validate', $prepared['proposal_id'], 'Rever histórico sem nova dívida', (string) Str::uuid());
|
|
expect($result['state'])->toBe('conflict')->and(DB::table('pa_obligations')->count())->toBe(0)
|
|
->and($payments->outstanding($this->f['invoice']))->toBe(2000);
|
|
});
|
|
|
|
test('activation does not grant permissions and source queries remain tenant scoped', function () {
|
|
DB::table('pa_access')->where('user_id', $this->f['author']->id)->delete();
|
|
$this->getJson('/api/supplier-payables')->assertForbidden();
|
|
$foreign = User::factory()->create(['tenant_id' => null]);
|
|
$this->actingAs($foreign);
|
|
expect(fn () => app(SupplierPayables::class)->principal($this->f['invoice']))->toThrow(HttpException::class);
|
|
config(['common-payables.enabled' => false]);
|
|
// Owned PostgreSQL QA fixtures have an explicit environment override; normal
|
|
// installations still require the configured activation flag.
|
|
$environment = app()->environment();
|
|
app()->detectEnvironment(fn () => 'local');
|
|
try {
|
|
expect(SupplierPayables::enabled())->toBeFalse();
|
|
} finally {
|
|
app()->detectEnvironment(fn () => $environment);
|
|
}
|
|
});
|
|
|
|
test('the shared schema preserves histories and refuses repeated or partial installation', function () {
|
|
expect(fn () => PayablesSchema::install())->toThrow(LogicException::class);
|
|
$service = app(SupplierPayables::class);
|
|
$service->engine($this->f['author'])->command('prepare', $this->f['invoice']->id, 'Criar histórico imutável de teste', (string) Str::uuid());
|
|
expect(fn () => DB::table('pa_events')->delete())->toThrow(QueryException::class);
|
|
});
|
|
|
|
test('navigation exposes the workspace only while the current actor has explicit view access', function () {
|
|
$this->get('/dashboard')->assertOk()->assertInertia(fn ($page) => $page->where('payablesAvailable', true));
|
|
DB::table('pa_access')->where('user_id', $this->f['author']->id)->where('action', 'view')->delete();
|
|
$this->get('/dashboard')->assertOk()->assertInertia(fn ($page) => $page->where('payablesAvailable', false));
|
|
$this->get('/obrigacoes-fornecedores')->assertForbidden();
|
|
});
|