systemDirectory, '\\/ ') . DIRECTORY_SEPARATOR . 'bootstrap.php'; require_once SYSTEMPATH . 'Config/DotEnv.php'; (new CodeIgniter\Config\DotEnv(ROOTPATH))->load(); defined('ENVIRONMENT') || define('ENVIRONMENT', env('CI_ENVIRONMENT', 'development')); $boot = APPPATH . 'Config/Boot/' . ENVIRONMENT . '.php'; if (is_file($boot)) { require_once $boot; } use App\Controllers\EmployeeRestController; use CodeIgniter\HTTP\IncomingRequest; use CodeIgniter\HTTP\URI; use CodeIgniter\HTTP\UserAgent; use Config\Services; $pass = 0; $fail = 0; $skip = 0; $results = []; function ok(string $label, bool $cond, string $detail = ''): void { global $pass, $fail, $results; if ($cond) { $pass++; $results[] = '[PASS] ' . $label . ($detail !== '' ? " — {$detail}" : ''); } else { $fail++; $results[] = '[FAIL] ' . $label . ($detail !== '' ? " — {$detail}" : ''); } } function skip(string $label, string $detail = ''): void { global $skip, $results; $skip++; $results[] = '[SKIP] ' . $label . ($detail !== '' ? " — {$detail}" : ''); } /** * @return array{http:int,body:array,raw:string,error:?string} */ function invokeGetEmployeeAndDependenceByClientId(array $query): array { try { $uri = new URI('http://localhost/nhance_v2/employeeRest/getEmployeeAndDependenceByClientId'); if ($query !== []) { $uri->setQuery(http_build_query($query)); } $request = new IncomingRequest( config('App'), $uri, null, new UserAgent() ); $request->setMethod('get'); $request->setGlobal('get', $query); $controller = new EmployeeRestController(); $response = Services::response(); $logger = Services::logger(); $controller->initController($request, $response, $logger); $resp = $controller->getEmployeeAndDependenceByClientId(); $raw = $resp->getBody(); $body = json_decode($raw, true); return [ 'http' => $resp->getStatusCode(), 'body' => is_array($body) ? $body : [], 'raw' => (string) $raw, 'error' => null, ]; } catch (Throwable $e) { return [ 'http' => 500, 'body' => [], 'raw' => '', 'error' => $e->getMessage() . ' @ ' . $e->getFile() . ':' . $e->getLine(), ]; } } function rowMatchesSearch(array $row, string $search): bool { $needle = mb_strtolower(trim($search)); if ($needle === '') { return true; } $haystacks = [ (string) ($row['emp_code'] ?? ''), (string) ($row['name'] ?? ''), (string) ($row['mobile'] ?? ''), (string) ($row['email_corporate'] ?? ''), (string) ($row['tpa_id'] ?? ''), (string) ($row['dob'] ?? ''), (string) ($row['formatted_dob'] ?? ''), (string) ($row['relationship'] ?? ''), (string) ($row['status'] ?? ''), (string) ($row['emp_status'] ?? ''), ]; foreach ($haystacks as $hay) { if ($hay !== '' && mb_stripos($hay, $needle) !== false) { return true; } } return false; } // ─── Fixtures ──────────────────────────────────────────────────────────────── $db = db_connect('default'); $cliClientId = $argv[1] ?? null; $cliClientPolicyId = isset($argv[2]) && ctype_digit((string) $argv[2]) ? (int) $argv[2] : null; $cliClientBranchId = isset($argv[3]) && ctype_digit((string) $argv[3]) ? (int) $argv[3] : null; $fixtureSql = " SELECT emp.client_id, MD5(emp.client_id) AS client_id_md5, emp.client_branch_id, ep.client_policy_id, emp.emp_code, emp.name, emp.mobile, emp.email_corporate, ep.tpa_id, emp.dob, DATE_FORMAT(emp.dob, '%d/%m/%Y') AS formatted_dob, emp.relationship, ep.status, emp.emp_status FROM employee_polices ep INNER JOIN employees emp ON emp.id = ep.employee_id WHERE ep.is_active = 1 AND emp.is_active = 1 AND ep.status IN ('active', 'inactive') "; $bindings = []; if ($cliClientId !== null && $cliClientId !== '') { if (is_string($cliClientId) && preg_match('/^[a-f0-9]{32}$/i', $cliClientId)) { $fixtureSql .= ' AND MD5(emp.client_id) = ?'; $bindings[] = $cliClientId; } else { $fixtureSql .= ' AND emp.client_id = ?'; $bindings[] = (int) $cliClientId; } } if ($cliClientPolicyId !== null) { $fixtureSql .= ' AND ep.client_policy_id = ?'; $bindings[] = $cliClientPolicyId; } if ($cliClientBranchId !== null) { $fixtureSql .= ' AND emp.client_branch_id = ?'; $bindings[] = $cliClientBranchId; } // Prefer a row that has searchable fields populated (mobile/email/tpa_id). $fixtureSql .= ' ORDER BY (emp.mobile IS NOT NULL AND emp.mobile <> "") DESC, (emp.email_corporate IS NOT NULL AND emp.email_corporate <> "") DESC, (ep.tpa_id IS NOT NULL AND ep.tpa_id <> "") DESC, ep.id DESC LIMIT 1 '; $fixture = $db->query($fixtureSql, $bindings)->getRowArray(); if (!$fixture) { echo "No fixture rows found for employee_polices + employees.\n"; echo "Pass args: php tests/smoke_get_employee_and_dependence_by_client_id.php [client_id] [client_policy_id] [client_branch_id]\n"; exit(1); } $baseQuery = [ 'client_id' => (string) $fixture['client_id_md5'], 'client_policy_id' => (string) $fixture['client_policy_id'], 'client_branch_id' => (string) $fixture['client_branch_id'], ]; echo "Fixture:\n"; echo json_encode([ 'client_id' => $fixture['client_id'], 'client_id_md5' => $fixture['client_id_md5'], 'client_policy_id' => $fixture['client_policy_id'], 'client_branch_id' => $fixture['client_branch_id'], 'emp_code' => $fixture['emp_code'], 'name' => $fixture['name'], 'mobile' => $fixture['mobile'], 'email_corporate' => $fixture['email_corporate'], 'tpa_id' => $fixture['tpa_id'], 'dob' => $fixture['dob'], 'formatted_dob' => $fixture['formatted_dob'], 'relationship' => $fixture['relationship'], 'status' => $fixture['status'], 'emp_status' => $fixture['emp_status'], ], JSON_PRETTY_PRINT) . "\n\n"; // ─── Baseline (no search) ──────────────────────────────────────────────────── $baseline = invokeGetEmployeeAndDependenceByClientId($baseQuery); ok( 'Baseline call has no PHP error', $baseline['error'] === null, (string) ($baseline['error'] ?? '') ); ok( 'Baseline returns success/200 with non-empty data', ($baseline['body']['status'] ?? '') === 'success' && (int) ($baseline['body']['code'] ?? 0) === 200 && is_array($baseline['body']['data'] ?? null) && count($baseline['body']['data']) > 0, 'http=' . $baseline['http'] . ' count=' . count($baseline['body']['data'] ?? []) . ' body_status=' . ($baseline['body']['status'] ?? '') ); $baselineRows = is_array($baseline['body']['data'] ?? null) ? $baseline['body']['data'] : []; $baselineCount = count($baselineRows); // Empty search should behave like no search $emptySearch = invokeGetEmployeeAndDependenceByClientId($baseQuery + ['search' => '']); ok( 'Empty search returns same count as baseline', ($emptySearch['error'] ?? null) === null && count($emptySearch['body']['data'] ?? []) === $baselineCount, 'baseline=' . $baselineCount . ' empty_search=' . count($emptySearch['body']['data'] ?? []) ); // Nonsense search → failed/404 empty $nonsense = invokeGetEmployeeAndDependenceByClientId($baseQuery + ['search' => '___no_such_value_zzz_999___']); ok( 'Nonsense search returns failed/404 empty data', ($nonsense['body']['status'] ?? '') === 'failed' && (int) ($nonsense['body']['code'] ?? 0) === 404 && ($nonsense['body']['data'] ?? null) === [], json_encode($nonsense['body']) ); // ─── Per-field search cases ────────────────────────────────────────────────── $searchCases = [ 'emp_code' => (string) ($fixture['emp_code'] ?? ''), 'name' => (string) ($fixture['name'] ?? ''), 'mobile' => (string) ($fixture['mobile'] ?? ''), 'email' => (string) ($fixture['email_corporate'] ?? ''), 'tpa_id' => (string) ($fixture['tpa_id'] ?? ''), 'dob' => (string) ($fixture['dob'] ?? ''), 'formatted_dob'=> (string) ($fixture['formatted_dob'] ?? ''), 'relationship' => (string) ($fixture['relationship'] ?? ''), 'status' => (string) ($fixture['status'] ?? ''), ]; foreach ($searchCases as $field => $value) { $value = trim($value); if ($value === '') { skip("Search by {$field}", 'fixture value empty'); continue; } // Use a short distinctive fragment when the value is long (e.g. name/email) $term = $value; if (in_array($field, ['name', 'email'], true) && mb_strlen($value) > 4) { $term = mb_substr($value, 0, max(3, (int) floor(mb_strlen($value) / 2))); } $resp = invokeGetEmployeeAndDependenceByClientId($baseQuery + ['search' => $term]); $rows = is_array($resp['body']['data'] ?? null) ? $resp['body']['data'] : []; ok( "Search by {$field} returns success with rows", ($resp['error'] ?? null) === null && ($resp['body']['status'] ?? '') === 'success' && (int) ($resp['body']['code'] ?? 0) === 200 && count($rows) > 0, 'term=' . $term . ' count=' . count($rows) . ' err=' . ($resp['error'] ?? '') ); $allMatch = true; foreach ($rows as $row) { if (!rowMatchesSearch($row, $term)) { $allMatch = false; break; } } ok( "Search by {$field}: every returned row matches term", $allMatch && count($rows) > 0, 'term=' . $term . ' rows=' . count($rows) ); ok( "Search by {$field}: result count <= baseline", count($rows) <= $baselineCount, 'filtered=' . count($rows) . ' baseline=' . $baselineCount ); } // Partial emp_code (if long enough) $empCode = trim((string) ($fixture['emp_code'] ?? '')); if (mb_strlen($empCode) >= 3) { $partial = mb_substr($empCode, 0, 3); $resp = invokeGetEmployeeAndDependenceByClientId($baseQuery + ['search' => $partial]); $rows = is_array($resp['body']['data'] ?? null) ? $resp['body']['data'] : []; ok( 'Partial emp_code search returns matching rows', ($resp['body']['status'] ?? '') === 'success' && count($rows) > 0, 'term=' . $partial . ' count=' . count($rows) ); } else { skip('Partial emp_code search', 'emp_code too short'); } // MD5 client_id already used above; also verify numeric client_id works without search $numericQuery = [ 'client_id' => (string) $fixture['client_id'], 'client_policy_id' => (string) $fixture['client_policy_id'], 'client_branch_id' => (string) $fixture['client_branch_id'], ]; $numeric = invokeGetEmployeeAndDependenceByClientId($numericQuery); ok( 'Numeric client_id baseline returns success', ($numeric['body']['status'] ?? '') === 'success' && count($numeric['body']['data'] ?? []) > 0, 'count=' . count($numeric['body']['data'] ?? []) ); // Optional: if a search term was passed as 4th argv, dump raw result if (isset($argv[4]) && trim((string) $argv[4]) !== '') { $manualTerm = trim((string) $argv[4]); $manual = invokeGetEmployeeAndDependenceByClientId($baseQuery + ['search' => $manualTerm]); echo "\nManual search term={$manualTerm}\n"; echo json_encode([ 'http' => $manual['http'], 'error' => $manual['error'], 'status'=> $manual['body']['status'] ?? null, 'code' => $manual['body']['code'] ?? null, 'count' => count($manual['body']['data'] ?? []), 'first' => ($manual['body']['data'][0] ?? null), ], JSON_PRETTY_PRINT) . "\n"; } echo "\nSmoke test summary: {$pass} passed, {$fail} failed, {$skip} skipped\n"; foreach ($results as $line) { echo $line . "\n"; } exit($fail > 0 ? 1 : 0);