FIX_HR_CLAIM

This commit is contained in:
VENKATESHWARAN 2026-07-15 11:14:56 +05:30
parent 5077ed30c6
commit ab3a99e9b0
2 changed files with 513 additions and 1 deletions

View File

@ -853,8 +853,70 @@ class RestAuthenticationController extends AdminController
if (!empty($HRAccessData) && isset($HRAccessData['allowed_modules'])) {
$decoded = json_decode($HRAccessData['allowed_modules'], true);
// $decoded = json_decode($HRAccessData['allowed_modules'], true);
// $getAllhrData[$key]['allowed_modules'] = $decoded;
// $HRAccessData['pre_client_id'] = md5($HRAccessData['pre_client_id']);
// $HRAccessData['post_client_id'] = md5($HRAccessData['post_client_id']);
$decoded = json_decode($HRAccessData['allowed_modules'], true) ?? [];
$allowedActivePolicies = json_decode($HRAccessData['allowed_active_policies'] ?? '[]', true) ?? [];
if (!is_array($allowedActivePolicies)) {
$allowedActivePolicies = [];
}
if (empty($allowedActivePolicies) && is_array($decoded)) {
if (isset($decoded['post']) && is_array($decoded['post'])) {
$decoded['post'] = array_values(array_filter(
$decoded['post'],
static fn($module) => (int) $module !== 4
));
} elseif (!isset($decoded['pre']) && !isset($decoded['post'])) {
$decoded = array_values(array_filter(
$decoded,
static fn($module) => (int) $module !== 4
));
}
$HRAccessData['allowed_modules'] = json_encode($decoded);
}
$claimsSubMenu = [];
$hasClaimsModule = false;
if (is_array($decoded)) {
if (isset($decoded['post']) && is_array($decoded['post'])) {
$hasClaimsModule = in_array(4, array_map('intval', $decoded['post']), true);
} elseif (!isset($decoded['pre']) && !isset($decoded['post'])) {
$hasClaimsModule = in_array(4, array_map('intval', $decoded), true);
}
}
if ($hasClaimsModule) {
$claimsSubMenu[] = 'EB';
$hasNonEbPolicy = false;
if (!empty($allowedActivePolicies)) {
$db = \Config\Database::connect();
$policyAllocgRows = $db->table('client_policy')
->select('policy_type.allocg')
->join('policy_type', 'policy_type.id = client_policy.policy_type_id', 'left')
->whereIn('client_policy.id', $allowedActivePolicies)
->get()
->getResultArray();
foreach ($policyAllocgRows as $policyRow) {
if (($policyRow['allocg'] ?? '') !== 'EB') {
$hasNonEbPolicy = true;
break;
}
}
}
if ($hasNonEbPolicy) {
$claimsSubMenu[] = 'Non-EB';
}
}
$getAllhrData[$key]['allowed_modules'] = $decoded;
$getAllhrData[$key]['claims_sub_menu'] = $claimsSubMenu;
$HRAccessData['pre_client_id'] = md5($HRAccessData['pre_client_id']);
$HRAccessData['post_client_id'] = md5($HRAccessData['post_client_id']);

View File

@ -0,0 +1,450 @@
<?php
namespace Tests\Unit;
use App\Controllers\RestAuthenticationController;
use App\Models\AuthHistoryModel;
use App\Models\LevelContactModel;
use CodeIgniter\HTTP\IncomingRequest;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\HTTP\URI;
use CodeIgniter\Test\CIUnitTestCase;
use Config\Database as DatabaseConfig;
use Config\Services;
use ReflectionClass;
use ReflectionProperty;
class GetVerifiedHrDataTest extends CIUnitTestCase
{
private string $jwtSecret = 'test-secret-key-for-get-verified-hr-data';
protected function setUp(): void
{
parent::setUp();
putenv("JWT_SECRET={$this->jwtSecret}");
$_ENV['JWT_SECRET'] = $this->jwtSecret;
$_SERVER['JWT_SECRET'] = $this->jwtSecret;
putenv('POST_ENROLLMENT_BASEURL=http://example.com/');
$_ENV['POST_ENROLLMENT_BASEURL'] = 'http://example.com/';
$this->mockCurlRequest(['ok' => true, 'source' => 'post_enrollment']);
$this->mockRateLimiter();
}
protected function tearDown(): void
{
$this->clearInjectedDbConnections();
Services::reset(true);
putenv('JWT_SECRET');
putenv('POST_ENROLLMENT_BASEURL');
unset(
$_ENV['JWT_SECRET'],
$_SERVER['JWT_SECRET'],
$_ENV['POST_ENROLLMENT_BASEURL']
);
parent::tearDown();
}
public function testInvalidOtpReturnsFailed404()
{
$hrModel = $this->createHrModelStub([
'first' => null,
'findAll' => [],
]);
$controller = $this->buildController(
['email' => 'hr@example.com', 'otp' => '000000'],
$hrModel
);
$body = $this->decodeResponse($controller->getVerifiedHrData());
$this->assertSame('failed', $body['status']);
$this->assertSame(404, $body['code']);
$this->assertSame('', $body['data']);
$this->assertSame(['ok' => true, 'source' => 'post_enrollment'], $body['post_enrollment']);
}
public function testValidOtpWithNoActiveBranchesReturnsFailed404()
{
$hrModel = $this->createHrModelStub([
'first' => ['id' => 5, 'email' => 'hr@example.com', 'mobile' => '9876543210'],
'findAll' => [],
'update' => true,
]);
$authHistoryModel = $this->createMock(AuthHistoryModel::class);
$authHistoryModel->expects($this->once())->method('insert');
$controller = $this->buildController(
['email' => 'hr@example.com', 'otp' => '123456'],
$hrModel,
$authHistoryModel
);
$body = $this->decodeResponse($controller->getVerifiedHrData());
$this->assertSame('failed', $body['status']);
$this->assertSame(404, $body['code']);
$this->assertSame('', $body['data']);
}
public function testValidMobileOtpReturnsSuccessWithClaimsSubMenu()
{
$branchRow = [
'id' => 5,
'mobile' => '9876543210',
'email' => 'hr@example.com',
'client_id' => 42,
'client_name' => 'Acme Corp',
'short_name' => 'ACME',
'client_branch_id' => 7,
'branch_name' => 'HQ',
'post_branch_id' => 70,
];
$hrModel = $this->createHrModelStub([
'first' => ['id' => 5, 'email' => 'hr@example.com', 'mobile' => '9876543210'],
'findAll' => [$branchRow],
'update' => true,
]);
$authHistoryModel = $this->createMock(AuthHistoryModel::class);
$authHistoryModel->expects($this->once())->method('insert');
$this->injectDbConnection('postDB', $this->createQueryResultStub([
'pre_client_id' => 42,
'post_client_id' => 420,
'pre_branch_id' => 7,
'pre_hr_id' => 5,
'allowed_modules' => json_encode(['post' => [1, 4, 5]]),
'allowed_active_policies' => json_encode([101, 102]),
]));
$this->injectDbConnection('tests', $this->createQueryResultStub(
null,
[
['allocg' => 'EB'],
['allocg' => 'GPA'],
]
));
$controller = $this->buildController(
['mobile_no' => '9876543210', 'otp' => '123456'],
$hrModel,
$authHistoryModel
);
$body = $this->decodeResponse($controller->getVerifiedHrData());
$this->assertSame('success', $body['status']);
$this->assertSame(200, $body['code']);
$this->assertCount(1, $body['data']);
$this->assertSame(['post' => [1, 4, 5]], $body['data'][0]['allowed_modules']);
$this->assertSame(['EB', 'Non-EB'], $body['data'][0]['claims_sub_menu']);
$this->assertNotEmpty($body['data'][0]['token']);
$this->assertSame(['ok' => true, 'source' => 'post_enrollment'], $body['post_enrollment']);
}
public function testClaimsModuleWithoutActivePoliciesStripsModuleId4()
{
$branchRow = [
'id' => 5,
'mobile' => null,
'email' => 'hr@example.com',
'client_id' => 42,
'client_name' => 'Acme Corp',
'short_name' => 'ACME',
'client_branch_id' => 7,
'branch_name' => 'HQ',
'post_branch_id' => 70,
];
$hrModel = $this->createHrModelStub([
'first' => ['id' => 5, 'email' => 'hr@example.com', 'mobile' => null],
'findAll' => [$branchRow],
'update' => true,
]);
$authHistoryModel = $this->createMock(AuthHistoryModel::class);
$authHistoryModel->method('insert')->willReturn(1);
$this->injectDbConnection('postDB', $this->createQueryResultStub([
'pre_client_id' => 42,
'post_client_id' => 420,
'pre_branch_id' => 7,
'pre_hr_id' => 5,
'allowed_modules' => json_encode(['post' => [1, 4, 5]]),
'allowed_active_policies' => json_encode([]),
]));
$controller = $this->buildController(
['email' => 'hr@example.com', 'otp' => '123456'],
$hrModel,
$authHistoryModel
);
$body = $this->decodeResponse($controller->getVerifiedHrData());
$this->assertSame('success', $body['status']);
$this->assertSame(['post' => [1, 5]], $body['data'][0]['allowed_modules']);
$this->assertSame([], $body['data'][0]['claims_sub_menu']);
$this->assertNotEmpty($body['data'][0]['token']);
}
public function testMissingHrAccessReturnsEmptyModulesAndEmptyToken()
{
$branchRow = [
'id' => 5,
'mobile' => '9876543210',
'email' => 'hr@example.com',
'client_id' => 42,
'client_name' => 'Acme Corp',
'short_name' => 'ACME',
'client_branch_id' => 7,
'branch_name' => 'HQ',
'post_branch_id' => 70,
];
$hrModel = $this->createHrModelStub([
'first' => ['id' => 5, 'email' => 'hr@example.com', 'mobile' => '9876543210'],
'findAll' => [$branchRow],
'update' => true,
]);
$authHistoryModel = $this->createMock(AuthHistoryModel::class);
$authHistoryModel->method('insert')->willReturn(1);
$this->injectDbConnection('postDB', $this->createQueryResultStub(null));
$controller = $this->buildController(
['mobile_no' => '9876543210', 'otp' => '123456'],
$hrModel,
$authHistoryModel
);
$body = $this->decodeResponse($controller->getVerifiedHrData());
$this->assertSame('success', $body['status']);
$this->assertSame(200, $body['code']);
$this->assertSame([], $body['data'][0]['allowed_modules']);
$this->assertSame('', $body['data'][0]['token']);
}
private function buildController(
array $payload,
object $hrModel,
?AuthHistoryModel $authHistoryModel = null
): RestAuthenticationController {
$json = (object) $payload;
$uri = $this->createMock(URI::class);
$uri->method('getPath')->willReturn('/employeeRest/getVerifiedHrData');
$uri->method('getSegments')->willReturn(['employeeRest', 'getVerifiedHrData']);
$request = $this->getMockBuilder(IncomingRequest::class)
->disableOriginalConstructor()
->onlyMethods([
'getJSON',
'getHeaderLine',
'getIPAddress',
'getMethod',
'getPost',
'getVar',
])
->getMock();
$request->uri = $uri;
$request->method('getJSON')->willReturn($json);
$request->method('getHeaderLine')->with('User-Agent')->willReturn('PHPUnit');
$request->method('getIPAddress')->willReturn('127.0.0.1');
$request->method('getMethod')->willReturn('post');
$request->method('getPost')->willReturn([]);
$request->method('getVar')->willReturnCallback(static function ($key) {
return match ($key) {
'rateLimitFingerprint' => 'test-fingerprint',
'rateLimitIdentity' => 'hr@example.com',
default => null,
};
});
Services::injectMock('request', $request);
$controller = new RestAuthenticationController();
$controller->initController($request, Services::response(), Services::logger());
$reflection = new ReflectionClass($controller);
$hrProp = $reflection->getProperty('hrModel');
$hrProp->setAccessible(true);
$hrProp->setValue($controller, $hrModel);
if ($authHistoryModel !== null) {
$authProp = $reflection->getProperty('authHistoryModel');
$authProp->setAccessible(true);
$authProp->setValue($controller, $authHistoryModel);
}
return $controller;
}
private function createHrModelStub(array $results): object
{
return new class ($results) {
private array $results;
private $setPayload = null;
public function __construct(array $results)
{
$this->results = $results;
}
public function select(...$args)
{
return $this;
}
public function join(...$args)
{
return $this;
}
public function where(...$args)
{
return $this;
}
public function set($data)
{
$this->setPayload = $data;
return $this;
}
public function first()
{
return $this->results['first'] ?? null;
}
public function findAll()
{
return $this->results['findAll'] ?? [];
}
public function update(...$args)
{
return $this->results['update'] ?? true;
}
};
}
/**
* Fluent DB stub returning either a single row (getRowArray) or many rows (getResultArray).
*/
private function createQueryResultStub(?array $row, array $rows = []): object
{
return new class ($row, $rows) {
private ?array $row;
private array $rows;
public function __construct(?array $row, array $rows)
{
$this->row = $row;
$this->rows = $rows;
}
public function table(...$args)
{
return $this;
}
public function select(...$args)
{
return $this;
}
public function join(...$args)
{
return $this;
}
public function where(...$args)
{
return $this;
}
public function whereIn(...$args)
{
return $this;
}
public function get()
{
return $this;
}
public function getRowArray(): ?array
{
return $this->row;
}
public function getResultArray(): array
{
return $this->rows;
}
};
}
private function injectDbConnection(string $group, object $connection): void
{
$property = new ReflectionProperty(DatabaseConfig::class, 'instances');
$property->setAccessible(true);
$instances = $property->getValue() ?? [];
$instances[$group] = $connection;
$property->setValue(null, $instances);
}
private function clearInjectedDbConnections(): void
{
$property = new ReflectionProperty(DatabaseConfig::class, 'instances');
$property->setAccessible(true);
$property->setValue(null, []);
}
private function mockCurlRequest(array $payload): void
{
$response = $this->createMock(ResponseInterface::class);
$response->method('getBody')->willReturn(json_encode($payload));
$curl = $this->getMockBuilder(\CodeIgniter\HTTP\CURLRequest::class)
->disableOriginalConstructor()
->onlyMethods(['post', 'get'])
->getMock();
$curl->method('post')->willReturn($response);
$curl->method('get')->willReturn($response);
Services::injectMock('curlrequest', $curl);
}
private function mockRateLimiter(): void
{
$limiter = $this->getMockBuilder(\App\Libraries\RateLimiterService::class)
->disableOriginalConstructor()
->onlyMethods(['recordIpFailure', 'recordUserFailure'])
->getMock();
$limiter->method('recordIpFailure')->willReturn(null);
$limiter->method('recordUserFailure')->willReturn(null);
Services::injectMock('limiter', $limiter);
}
private function decodeResponse($response): array
{
return json_decode($response->getBody(), true);
}
}