379 lines
13 KiB
PHP
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);
|