f = receiptFixture(); supplyGrant($this->f['receiver'], ['inventory_disposition_prepare', 'inventory_reversal_prepare']); $this->actingAs($this->f['receiver']); }); test('correction source access rechecks expired and maintenance profiles without writing', function (string $mode) { $service = app(InventoryCorrectionPage::class); $call = fn () => match ($mode) { 'receipts' => $service->receipts(collect()), 'operations' => $service->operations(collect()), default => $service->read(Request::create('/stock/estornos'), $this->f['receiver'], 'stock_reversal'), }; $call(); $before = DB::table('audit_logs')->count(); DB::table('organization_memberships')->where('user_id', $this->f['receiver']->id)->update(['maintenance' => true]); expect($call)->toThrow(HttpException::class); DB::table('organization_memberships')->where('user_id', $this->f['receiver']->id)->update(['maintenance' => false, 'expires_at' => now()->subMinute()]); expect($call)->toThrow(HttpException::class); expect(DB::table('audit_logs')->count())->toBe($before); })->with(['receipts', 'operations', 'records']); test('correction read permission does not grant preparation source access', function () { $viewer = User::factory()->create(['tenant_id' => $this->f['tenant']->id]); supplyGrant($viewer, ['inventory_disposition_read', 'inventory_reversal_read']); $this->actingAs($viewer); $service = app(InventoryCorrectionPage::class); expect($service->read(Request::create('/stock/estornos'), $viewer, 'stock_reversal')['ready'])->toBeTrue(); expect(fn () => $service->receipts(collect()))->toThrow(HttpException::class); expect(fn () => $service->operations(collect()))->toThrow(HttpException::class); });