array('pipe', 'w'), 2 => array('pipe', 'w')); $process = proc_open($command, $descriptor, $pipes, $root); self::assertIsResource($process, 'Tidak dapat menjalankan pemeriksaan integrasi CI3.'); $stdout = stream_get_contents($pipes[1]); $stderr = stream_get_contents($pipes[2]); fclose($pipes[1]); fclose($pipes[2]); $exit = proc_close($process); self::assertSame(0, $exit, trim($stderr . PHP_EOL . $stdout)); $result = json_decode($stdout, true); self::assertIsArray($result, 'Output Stage17check bukan JSON: ' . $stdout); self::assertSame('ok', $result['status']); foreach ($result['checks'] as $name => $check) { self::assertSame('pass', $check['status'], $name . ': ' . $check['detail']); } } public function testPurchaseAdjustmentInvariantsAgainstDevelopmentDatabase(): void { $root=dirname(__DIR__,2);$command=array(PHP_BINARY,$root.'/index.php','purchaseadjustmentcheck','integrity'); $descriptor=array(1=>array('pipe','w'),2=>array('pipe','w'));$process=proc_open($command,$descriptor,$pipes,$root); self::assertIsResource($process);$stdout=stream_get_contents($pipes[1]);$stderr=stream_get_contents($pipes[2]);fclose($pipes[1]);fclose($pipes[2]);$exit=proc_close($process); self::assertSame(0,$exit,trim($stderr.PHP_EOL.$stdout));$result=json_decode($stdout,true);self::assertIsArray($result,'Output Purchaseadjustmentcheck bukan JSON: '.$stdout);self::assertSame('ok',$result['status']); } public function testPurchaseAdjustmentQueriesAndReportsRunAgainstActualSchema(): void { $root=dirname(__DIR__,2);$command=array(PHP_BINARY,$root.'/index.php','purchaseadjustmentcheck','runtime'); $descriptor=array(1=>array('pipe','w'),2=>array('pipe','w'));$process=proc_open($command,$descriptor,$pipes,$root); self::assertIsResource($process);$stdout=stream_get_contents($pipes[1]);$stderr=stream_get_contents($pipes[2]);fclose($pipes[1]);fclose($pipes[2]);$exit=proc_close($process); self::assertSame(0,$exit,trim($stderr.PHP_EOL.$stdout));$result=json_decode($stdout,true);self::assertIsArray($result,'Output runtime Retur/Refund bukan JSON: '.$stdout);self::assertSame('ok',$result['status']);self::assertArrayHasKey('purchase_returns',$result['reports']);self::assertArrayHasKey('supplier_refunds',$result['reports']);self::assertArrayHasKey('supplier_debit_notes',$result['reports']); } public function testProfessionalInventoryRuntimeAgainstDevelopmentDatabase(): void { $root=dirname(__DIR__,2);$command=array(PHP_BINARY,$root.'/index.php','inventorycheck','professional'); $descriptor=array(1=>array('pipe','w'),2=>array('pipe','w'));$process=proc_open($command,$descriptor,$pipes,$root); self::assertIsResource($process);$stdout=stream_get_contents($pipes[1]);$stderr=stream_get_contents($pipes[2]);fclose($pipes[1]);fclose($pipes[2]);$exit=proc_close($process); self::assertSame(0,$exit,trim($stderr.PHP_EOL.$stdout));$result=json_decode($stdout,true);self::assertIsArray($result,'Output Inventorycheck bukan JSON: '.$stdout);self::assertSame('ok',$result['status']);self::assertArrayHasKey('reconciliation',$result); } public function testInventoryIntegrityAndNegativeStockGuardAgainstDevelopmentDatabase(): void { $root=dirname(__DIR__,2); foreach(array('integrity','trigger_test') as$action){$command=array(PHP_BINARY,$root.'/index.php','inventorycheck',$action);$descriptor=array(1=>array('pipe','w'),2=>array('pipe','w'));$process=proc_open($command,$descriptor,$pipes,$root);self::assertIsResource($process);$stdout=stream_get_contents($pipes[1]);$stderr=stream_get_contents($pipes[2]);fclose($pipes[1]);fclose($pipes[2]);$exit=proc_close($process);self::assertSame(0,$exit,$action.': '.trim($stderr.PHP_EOL.$stdout));self::assertStringContainsString('[OK]',$stdout,$action.' tidak menghasilkan bukti pemeriksaan.');} } public function testInventoryReconciliationAlwaysProducesAuditableNumbers(): void { $root=dirname(__DIR__,2);$command=array(PHP_BINARY,$root.'/index.php','inventorycheck','reconciliation');$descriptor=array(1=>array('pipe','w'),2=>array('pipe','w'));$process=proc_open($command,$descriptor,$pipes,$root);self::assertIsResource($process);$stdout=stream_get_contents($pipes[1]);$stderr=stream_get_contents($pipes[2]);fclose($pipes[1]);fclose($pipes[2]);$exit=proc_close($process);self::assertContains($exit,array(0,1),trim($stderr.PHP_EOL.$stdout));self::assertStringContainsString('ledger_value=',$stdout);self::assertStringContainsString('gl_value=',$stdout);self::assertStringContainsString('difference=',$stdout); } public function testFixedAssetIntegrityAndRuntimeQueries(): void { $root=dirname(__DIR__,2);$command=array(PHP_BINARY,$root.'/index.php','fixedassetcheck'); $descriptor=array(1=>array('pipe','w'),2=>array('pipe','w'));$process=proc_open($command,$descriptor,$pipes,$root); self::assertIsResource($process);$stdout=stream_get_contents($pipes[1]);$stderr=stream_get_contents($pipes[2]);fclose($pipes[1]);fclose($pipes[2]);$exit=proc_close($process); self::assertSame(0,$exit,trim($stderr.PHP_EOL.$stdout));self::assertStringContainsString('Fixed asset integrity checks passed.',$stdout);self::assertStringContainsString('model_query_smoke_company_',$stdout); } }