['pipe', 'w'], 2 => ['pipe', 'w']], $pipes); $output = stream_get_contents($pipes[1]); $error = stream_get_contents($pipes[2]); fclose($pipes[1]); fclose($pipes[2]); expect(proc_close($process))->toBe(0)->and($error)->toBe(''); $result = json_decode($output, true, 512, JSON_THROW_ON_ERROR); $exempt = !in_array($mode, ['inactive', 'disabled', 'openid', 'other-page'], true); expect($result['exempt'])->toBe($exempt)->and($result['csrf'])->toBe($exempt); expect($result['login'])->toBe($mode === 'success')->and($result['replay'])->toBeFalse(); if ($mode === 'success') { expect($result['username'])->toBe('alice@example.test'); } })->with(['success', 'mismatch', 'missing', 'unsigned', 'tampered', 'inactive', 'disabled', 'openid', 'other-page']);