f = suggestionFixture(); $this->actingAs($this->f['receiver']); app(SupplyPlanning::class)->save($this->f['receiver'], 'policy', supplyInput([], 'suspend', $this->f['policy'])); $this->data = [...supplyPolicy($this->f), 'purpose' => 'internal', 'agreement_key' => $this->f['agreement']->record_key]; $this->actingAs($this->f['issuer']); $this->draft = app(SupplyPlanning::class)->save($this->f['issuer'], 'policy', supplyInput($this->data)); $this->path = '/compras/fornecimento?view=calendar&record_id='.$this->draft->id; }); test('supply task policy reaches an independent reviewer and a stale link shows the new state without approving twice', function () { supplyGrant($this->f['issuer'], ['supply_review']); $this->get('/requisicoes/tarefas?module=supply')->assertInertia(fn (Assert $page) => $page->where('tasks.total', 0)); $this->get($this->path)->assertInertia(fn (Assert $page) => $page->where('records.0.canApprove', false)->where('records.0.canReturn', false)); $this->actingAs($this->f['receiver'])->get('/requisicoes/tarefas?module=supply')->assertInertia(fn (Assert $page) => $page->where('tasks.total', 1) ->where('tasks.data.0.href', $this->path.'#supply-record-'.$this->draft->id)->missing('tasks.data.0.data')->missing('tasks.data.0.snapshot')); $before = [SupplyRecord::query()->count(), DB::table('audit_logs')->count(), DB::table('requisitions')->count()]; $this->get($this->path)->assertHeader('Cache-Control', 'max-age=0, no-store, private')->assertInertia(fn (Assert $page) => $page->has('records', 1) ->where('focusRecordId', $this->draft->id)->where('focusChanged', false)->where('records.0.canApprove', true)->where('records.0.canSuspend', false)); expect([SupplyRecord::query()->count(), DB::table('audit_logs')->count(), DB::table('requisitions')->count()])->toBe($before); $approved = app(SupplyPlanning::class)->save($this->f['receiver'], 'policy', supplyInput([], 'approve', $this->draft)); $this->get('/requisicoes/tarefas?module=supply')->assertInertia(fn (Assert $page) => $page->where('tasks.total', 0)); $this->get($this->path)->assertInertia(fn (Assert $page) => $page->where('focusChanged', true)->where('records.0.id', $approved->id) ->where('records.0.canApprove', false)->where('records.0.canSuspend', true)); }); test('supply task excludes every preparation contributor even after another person edits the current version', function () { supplyGrant($this->f['issuer'], ['supply_review']); supplyGrant($this->f['receiver'], ['supply_prepare']); $this->actingAs($this->f['receiver']); $updated = app(SupplyPlanning::class)->save($this->f['receiver'], 'policy', supplyInput([...$this->data, 'basis' => 'Revisão sintética conservando os intervenientes.'], 'save', $this->draft)); supplyGrant($this->f['otherReceiver'], ['supply_review']); foreach ([$this->f['issuer'], $this->f['receiver']] as $contributor) { $this->actingAs($contributor)->get('/requisicoes/tarefas?module=supply')->assertInertia(fn (Assert $page) => $page->where('tasks.total', 0)); expect(app(SupplyPlanning::class)->canReview($contributor, $updated))->toBeFalse(); } $this->actingAs($this->f['otherReceiver'])->get('/requisicoes/tarefas?module=supply')->assertInertia(fn (Assert $page) => $page->where('tasks.total', 1)->where('tasks.data.0.id', 'supply:'.$updated->id.':review')); }); test('supply task keeps a changed source available for return but cannot silently approve it', function () { $this->f['stock']->update(['name' => 'Cadastro alterado depois da preparação']); $this->actingAs($this->f['receiver'])->get('/requisicoes/tarefas?module=supply')->assertInertia(fn (Assert $page) => $page->where('tasks.total', 1)); $this->postJson('/compras/fornecimento/policy', supplyInput([], 'approve', $this->draft))->assertUnprocessable(); $returned = app(SupplyPlanning::class)->save($this->f['receiver'], 'policy', supplyInput([], 'return', $this->draft)); expect($returned->state)->toBe('returned')->and($returned->snapshot['item'])->toBe($this->draft->snapshot['item']); }); test('supply task retains older preparations across the former hundred row display limit', function () { $first = $this->draft; for ($index = 1; $index < 105; $index++) { app(SupplyPlanning::class)->save($this->f['issuer'], 'policy', supplyInput($this->data)); } $this->actingAs($this->f['receiver'])->get('/requisicoes/tarefas?module=supply')->assertInertia(fn (Assert $page) => $page->where('tasks.total', 105)->has('tasks.data', 25)->where('tasks.data.0.id', 'supply:'.$first->id.':review')); $this->get('/requisicoes/tarefas?module=supply&page=5')->assertInertia(fn (Assert $page) => $page->where('tasks.total', 105)->has('tasks.data', 5)); $this->get('/compras/fornecimento?view=calendar')->assertInertia(fn (Assert $page) => $page->has('records', 25)->where('recordPagination.total', 106)); $this->get($this->path)->assertInertia(fn (Assert $page) => $page->has('records', 1)->where('records.0.id', $first->id)->where('records.0.canApprove', true)); }); test('supply task and record focus preserve company isolation and the kind of the document', function () { $tenant = Tenant::query()->create(['name' => 'Outra empresa sintética']); $foreign = User::factory()->create(['tenant_id' => $tenant->id]); supplyGrant($foreign, ['supply_review']); $this->actingAs($foreign)->get('/requisicoes/tarefas?module=supply')->assertInertia(fn (Assert $page) => $page->where('tasks.total', 0)); $this->getJson($this->path)->assertUnprocessable(); $this->actingAs($this->f['receiver'])->getJson('/compras/fornecimento?view=agreements&record_id='.$this->draft->id)->assertUnprocessable(); }); test('supply task does not inherit execution from maintenance and expires with the saved grant', function () { DB::table('organization_memberships')->where('user_id', $this->f['receiver']->id)->update(['maintenance' => true, 'expires_at' => now()->addHour()]); $this->actingAs($this->f['receiver'])->get('/requisicoes/tarefas?module=supply')->assertInertia(fn (Assert $page) => $page->where('tasks.total', 0)); $this->get($this->path)->assertForbidden(); expect(app(SupplyPlanning::class)->canReview($this->f['receiver'], $this->draft))->toBeFalse(); DB::table('organization_memberships')->where('user_id', $this->f['receiver']->id)->update(['expires_at' => now()->subMinute()]); $this->get('/requisicoes/tarefas?module=supply')->assertForbidden(); });