nhance/tests/smoke_get_employee_and_dependence_by_client_id.php
2026-07-28 15:52:47 +05:30

379 lines
13 KiB
PHP

<?php
/**
* Smoke test: EmployeeRestController::getEmployeeAndDependenceByClientId (+ global search)
*
* Covers baseline list and search across:
* emp_code, name, mobile, email, tpa_id, dob, relationship, status
*
* Run:
* php tests/smoke_get_employee_and_dependence_by_client_id.php
* php tests/smoke_get_employee_and_dependence_by_client_id.php [client_id] [client_policy_id] [client_branch_id]
*
* client_id may be numeric or 32-char MD5 hash.
*/
declare(strict_types=1);
ob_start();
define('FCPATH', __DIR__ . '/../public/');
chdir(FCPATH);
require FCPATH . '../app/Config/Paths.php';
$paths = new Config\Paths();
require rtrim($paths->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);