nhance/tests/smoke_deletion_excel_optional_claim_status.php

204 lines
8.0 KiB
PHP

<?php
/**
* Smoke test: optional Claim status column for deletion Excel validation.
* Run: php tests/smoke_deletion_excel_optional_claim_status.php
*/
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;
}
helper('excel_util_helper');
use App\Controllers\EmployeeServiceController;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xls;
$pass = 0;
$fail = 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 getDeletionExcelColumns(EmployeeServiceController $controller): array
{
$property = new ReflectionProperty($controller, 'deletion_excel_columns');
$property->setAccessible(true);
return $property->getValue($controller);
}
function deletionColumnCountIsValid(array $columnsToCheck, array $excelHeaderRow): bool
{
$totalDefinedColumns = count($columnsToCheck);
$excelColumnsCount = count($excelHeaderRow);
$optionalColumnCount = 0;
foreach ($columnsToCheck as $columnConfig) {
if (!empty($columnConfig['is_column_optional'])) {
$optionalColumnCount++;
}
}
$minRequiredColumns = $totalDefinedColumns - $optionalColumnCount;
if ($optionalColumnCount > 0) {
return $excelColumnsCount >= $minRequiredColumns && $excelColumnsCount <= $totalDefinedColumns;
}
return $excelColumnsCount === $totalDefinedColumns;
}
function validateDeletionRowClaimStatus(array $columnsToCheck, array $row, string $currentColumnAction = 'D'): array
{
$result = ['error_summary' => [], 'error_data' => []];
$keys = array_keys($columnsToCheck);
$rowKey = 2;
foreach ($row as $colKey => $col) {
if (!isset($keys[$colKey])) {
continue;
}
$isMandatory = $columnsToCheck[$keys[$colKey]]['is_mandatory'];
$allowedValues = $columnsToCheck[$keys[$colKey]]['allowed_values'];
$columnName = $columnsToCheck[$keys[$colKey]]['col_name'];
$columnIndex = $columnsToCheck[$keys[$colKey]]['col_idx'];
if (is_bool($isMandatory) && $isMandatory === true && ($col === '' || $col === null)) {
$result['error_summary'][] = 1;
$result['error_data'][$rowKey][$keys[$colKey]]['error'][] = 'Value is mandatory';
}
if (
$currentColumnAction !== null
&& is_array($isMandatory)
&& in_array(strtoupper(trim($currentColumnAction)), $isMandatory, true)
&& ($col === '' || $col === null)
) {
$result['error_summary'][] = 1;
$result['error_data'][$rowKey][$keys[$colKey]]['error'][] = 'Value is mandatory for this action/event';
}
if (
($isMandatory === true && isset($allowedValues) && is_array($allowedValues))
|| (is_array($isMandatory) && isset($allowedValues) && is_array($allowedValues))
) {
if (!in_array(trim((string) $col), $allowedValues, true)) {
$result['error_summary'][] = 3;
$result['error_data'][$rowKey][$keys[$colKey]]['col_name'] = $columnName;
$result['error_data'][$rowKey][$keys[$colKey]]['col_idx'] = $columnIndex;
$result['error_data'][$rowKey][$keys[$colKey]]['error'][] = 'Value not allowed';
}
}
}
return $result;
}
$controller = new EmployeeServiceController();
$deletionColumns = getDeletionExcelColumns($controller);
$claimStatusColumn = $deletionColumns['claim_status'] ?? [];
$headerWithClaim = ['S.No', 'EMP ID', 'NAME OF EMP/DEP', 'Change event', 'Date of exit', 'Reason for exit', 'Claim status'];
$headerWithoutClaim = ['S.No', 'EMP ID', 'NAME OF EMP/DEP', 'Change event', 'Date of exit', 'Reason for exit'];
$sampleRowWithEmptyClaim = ['1', 'EMP001', 'Test Employee', 'deletion', '19-May-2026', 'Resigned', ''];
$sampleRowWithoutClaimCol = ['1', 'EMP001', 'Test Employee', 'deletion', '19-May-2026', 'Resigned'];
ok('claim_status is not mandatory', ($claimStatusColumn['is_mandatory'] ?? null) === false);
ok('claim_status column is optional', !empty($claimStatusColumn['is_column_optional']));
ok(
'claim_status has no allowed_values constraint',
!array_key_exists('allowed_values', $claimStatusColumn) || $claimStatusColumn['allowed_values'] === null
);
ok('7-column header passes column count check', deletionColumnCountIsValid($deletionColumns, $headerWithClaim));
ok('6-column header passes column count check', deletionColumnCountIsValid($deletionColumns, $headerWithoutClaim));
ok('5-column header fails column count check', !deletionColumnCountIsValid($deletionColumns, array_slice($headerWithoutClaim, 0, 5)));
ok('8-column header fails column count check', !deletionColumnCountIsValid($deletionColumns, array_merge($headerWithClaim, ['Extra'])));
$mismatchWithoutClaim = check_columns_name($deletionColumns, $headerWithoutClaim);
ok('header without Claim status has no column-name mismatch', count($mismatchWithoutClaim) === 0);
$mismatchWithClaim = check_columns_name($deletionColumns, $headerWithClaim);
ok('header with Claim status has no column-name mismatch', count($mismatchWithClaim) === 0);
$wrongHeader = $headerWithoutClaim;
$wrongHeader[5] = 'Wrong reason column';
$mismatchWrong = check_columns_name($deletionColumns, $wrongHeader);
ok('wrong required header is still detected', count($mismatchWrong) > 0);
$rowErrorsEmptyClaim = validateDeletionRowClaimStatus($deletionColumns, $sampleRowWithEmptyClaim);
ok(
'empty Claim status value does not fail row validation',
count($rowErrorsEmptyClaim['error_summary']) === 0,
'errors=' . count($rowErrorsEmptyClaim['error_summary'])
);
$rowErrorsMissingClaimCol = validateDeletionRowClaimStatus($deletionColumns, $sampleRowWithoutClaimCol);
ok(
'missing Claim status column does not fail row validation',
count($rowErrorsMissingClaimCol['error_summary']) === 0,
'errors=' . count($rowErrorsMissingClaimCol['error_summary'])
);
$tempDir = sys_get_temp_dir() . DIRECTORY_SEPARATOR;
$tempFileSixCols = $tempDir . 'smoke_deletion_6cols_' . date('Ymd_His') . '.xls';
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
foreach ($headerWithoutClaim as $idx => $header) {
$sheet->setCellValue(chr(65 + $idx) . '1', $header);
}
foreach ($sampleRowWithoutClaimCol as $idx => $value) {
$sheet->setCellValue(chr(65 + $idx) . '2', $value);
}
$writer = new Xls($spreadsheet);
$writer->save($tempFileSixCols);
$loadedSpreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($tempFileSixCols);
$loadedSheet = $loadedSpreadsheet->getActiveSheet();
$loadedHeader = $loadedSheet->rangeToArray('A1:F1')[0];
$loadedRow = $loadedSheet->rangeToArray('A2:F2')[0];
ok('generated 6-column xls header count is 6', count($loadedHeader) === 6);
ok('generated 6-column xls passes column count rule', deletionColumnCountIsValid($deletionColumns, $loadedHeader));
ok('generated 6-column xls passes header-name check', count(check_columns_name($deletionColumns, $loadedHeader)) === 0);
ok(
'generated 6-column xls row has no claim_status validation errors',
count(validateDeletionRowClaimStatus($deletionColumns, $loadedRow)['error_summary']) === 0
);
@unlink($tempFileSixCols);
echo PHP_EOL . implode(PHP_EOL, $results) . PHP_EOL;
echo PHP_EOL . "Summary: {$pass} passed, {$fail} failed" . PHP_EOL;
exit($fail > 0 ? 1 : 0);