298 lines
11 KiB
PHP
298 lines
11 KiB
PHP
<?php
|
|
|
|
namespace Tests\unit\Api;
|
|
|
|
use CodeIgniter\Test\CIUnitTestCase;
|
|
use App\Controllers\Api\NonEbClaimApiController;
|
|
|
|
/**
|
|
* Unit tests for NonEbClaimApiController::createClaim()
|
|
*
|
|
* Auth is controlled by overriding getAuthUser() in an anonymous subclass.
|
|
* Model dependencies are stubbed via ReflectionClass property injection.
|
|
*/
|
|
class CreateClaimTest extends CIUnitTestCase
|
|
{
|
|
// ─── Helpers ────────────────────────────────────────────────────────────
|
|
|
|
/**
|
|
* Build a controller subclass where getAuthUser() returns $user (or null).
|
|
*/
|
|
protected function makeController(?array $user = null): NonEbClaimApiController
|
|
{
|
|
$mockUser = $user;
|
|
|
|
$controller = new class($mockUser) extends NonEbClaimApiController {
|
|
private ?array $_mockUser;
|
|
|
|
public function __construct(?array $mockUser)
|
|
{
|
|
$this->_mockUser = $mockUser;
|
|
}
|
|
|
|
protected function getAuthUser(): ?array
|
|
{
|
|
return $this->_mockUser;
|
|
}
|
|
};
|
|
|
|
$request = \Config\Services::request();
|
|
$response = \Config\Services::response();
|
|
$logger = \Config\Services::logger();
|
|
$controller->initController($request, $response, $logger);
|
|
|
|
return $controller;
|
|
}
|
|
|
|
/**
|
|
* Build a minimal fluent stub model that returns $returnValue on ->first().
|
|
* Unknown chained method calls return $this (fluent builder pattern).
|
|
*/
|
|
protected function makeFluentStub(mixed $returnValue): object
|
|
{
|
|
return new class($returnValue) {
|
|
private mixed $rv;
|
|
private array $inserts = [];
|
|
|
|
public function __construct(mixed $rv) { $this->rv = $rv; }
|
|
|
|
public function __call(string $name, array $args): mixed
|
|
{
|
|
if ($name === 'first') return $this->rv;
|
|
if ($name === 'findAll') return is_array($this->rv) ? $this->rv : [$this->rv];
|
|
if ($name === 'insert') { $this->inserts[] = $args[0] ?? []; return 99; }
|
|
if ($name === 'insertID') return 99;
|
|
return $this; // fluent chain
|
|
}
|
|
|
|
public function getInserts(): array { return $this->inserts; }
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Inject a stub into a named property of the controller.
|
|
*/
|
|
protected function inject(NonEbClaimApiController $ctrl, string $property, object $stub): void
|
|
{
|
|
$ref = new \ReflectionClass($ctrl);
|
|
$prop = $ref->getProperty($property);
|
|
$prop->setAccessible(true);
|
|
$prop->setValue($ctrl, $stub);
|
|
}
|
|
|
|
/** Decode response body to array. */
|
|
protected function body(\CodeIgniter\HTTP\ResponseInterface $resp): array
|
|
{
|
|
return json_decode($resp->getBody(), true);
|
|
}
|
|
|
|
// ─── Tests ──────────────────────────────────────────────────────────────
|
|
|
|
public function testReturns401WhenNoAuth(): void
|
|
{
|
|
$ctrl = $this->makeController(null);
|
|
$resp = $ctrl->createClaim();
|
|
|
|
$this->assertSame(401, $resp->getStatusCode());
|
|
$body = $this->body($resp);
|
|
print_r($body);
|
|
$this->assertFalse($body['status']);
|
|
$this->assertSame(401, $body['code']);
|
|
}
|
|
|
|
public function testReturns400WhenRequiredFieldsMissing(): void
|
|
{
|
|
$_POST = []; // empty body — all required fields missing
|
|
|
|
$ctrl = $this->makeController(['id' => 1, 'name' => 'Test', 'email' => 't@t.com', 'mobile' => '9999']);
|
|
$resp = $ctrl->createClaim();
|
|
|
|
$this->assertSame(400, $resp->getStatusCode());
|
|
$body = $this->body($resp);
|
|
print_r($body);
|
|
$this->assertFalse($body['status']);
|
|
$this->assertSame(400, $body['code']);
|
|
$this->assertArrayHasKey('errors', $body);
|
|
$this->assertArrayHasKey('nature_of_loss', $body['errors']);
|
|
}
|
|
|
|
public function testReturns404WhenClientPolicyNotFound(): void
|
|
{
|
|
$_POST = [
|
|
'client_policy_id' => 8101,
|
|
'nature_of_loss' => 'Fire damage',
|
|
'loss_location' => 'Chennai',
|
|
'loss_date' => '22-03-2026',
|
|
];
|
|
|
|
$ctrl = $this->makeController(['id' => 1, 'name' => 'User', 'email' => 'u@t.com', 'mobile' => '999']);
|
|
|
|
// clientPolicyModel returns null — policy not found
|
|
$this->inject($ctrl, 'clientPolicyModel', $this->makeFluentStub(null));
|
|
|
|
$resp = $ctrl->createClaim();
|
|
|
|
$this->assertSame(404, $resp->getStatusCode());
|
|
$body = $this->body($resp);
|
|
print_r($body);
|
|
$this->assertFalse($body['status']);
|
|
$this->assertSame(404, $body['code']);
|
|
$this->assertStringContainsString('policy', strtolower($body['message']));
|
|
}
|
|
|
|
public function testReturns422WhenPolicyTypeIsEB(): void
|
|
{
|
|
$_POST = [
|
|
'client_policy_id' => 10,
|
|
'nature_of_loss' => 'Theft',
|
|
'loss_location' => 'Mumbai',
|
|
'loss_date' => '01-03-2026',
|
|
];
|
|
|
|
$ctrl = $this->makeController(['id' => 1, 'name' => 'User', 'email' => 'u@t.com', 'mobile' => '999']);
|
|
|
|
$this->inject($ctrl, 'clientPolicyModel', $this->makeFluentStub([
|
|
'id' => 10,
|
|
'client_id' => 5,
|
|
'client_branch_id' => 2,
|
|
'policy_type_id' => 3,
|
|
'insurer_id' => 7,
|
|
'policy_no' => 'POL/2026/001',
|
|
]));
|
|
|
|
// policyTypeModel returns EB — should be rejected
|
|
$this->inject($ctrl, 'policyTypeModel', $this->makeFluentStub(['allocg' => 'EB']));
|
|
|
|
$resp = $ctrl->createClaim();
|
|
|
|
$this->assertSame(422, $resp->getStatusCode());
|
|
$body = $this->body($resp);
|
|
print_r($body);
|
|
$this->assertFalse($body['status']);
|
|
$this->assertSame(422, $body['code']);
|
|
}
|
|
|
|
public function testReturns422WhenNoClaimStatusConfigured(): void
|
|
{
|
|
$_POST = [
|
|
'client_policy_id' => 10,
|
|
'nature_of_loss' => 'Flood',
|
|
'loss_location' => 'Kochi',
|
|
'loss_date' => '05-03-2026',
|
|
];
|
|
|
|
$ctrl = $this->makeController(['id' => 1, 'name' => 'User', 'email' => 'u@t.com', 'mobile' => '999']);
|
|
|
|
$this->inject($ctrl, 'clientPolicyModel', $this->makeFluentStub([
|
|
'id' => 10,
|
|
'client_id' => 5,
|
|
'client_branch_id' => 2,
|
|
'policy_type_id' => 10,
|
|
'insurer_id' => 7,
|
|
'policy_no' => 'POL/2026/002',
|
|
]));
|
|
$this->inject($ctrl, 'policyTypeModel', $this->makeFluentStub(['allocg' => 'Non-EB']));
|
|
$this->inject($ctrl, 'clientRMModel', $this->makeFluentStub(['user_id' => 4]));
|
|
// claimStatusModel returns null — no status configured
|
|
$this->inject($ctrl, 'claimStatusModel', $this->makeFluentStub(null));
|
|
|
|
$resp = $ctrl->createClaim();
|
|
|
|
$this->assertSame(422, $resp->getStatusCode());
|
|
$body = $this->body($resp);
|
|
print_r($body);
|
|
$this->assertFalse($body['status']);
|
|
$this->assertStringContainsString('status', strtolower($body['message']));
|
|
}
|
|
|
|
public function testReturns409OnDuplicateClaim(): void
|
|
{
|
|
$_POST = [
|
|
'client_policy_id' => 8101,
|
|
'nature_of_loss' => 'Fire accident one edited two',
|
|
'loss_location' => 'bjdbkkjb',
|
|
'loss_date' => '01-03-2026',
|
|
];
|
|
|
|
$ctrl = $this->makeController(['id' => 1, 'name' => 'User', 'email' => 'u@t.com', 'mobile' => '999']);
|
|
|
|
$this->inject($ctrl, 'clientPolicyModel', $this->makeFluentStub([
|
|
'id' => 10,
|
|
'client_id' => 12,
|
|
'client_branch_id' => 2,
|
|
'policy_type_id' => 10,
|
|
'insurer_id' => 7,
|
|
'policy_no' => 'POL/2026/DUPJHBVJH',
|
|
]));
|
|
$this->inject($ctrl, 'policyTypeModel', $this->makeFluentStub(['allocg' => 'Non-EB']));
|
|
$this->inject($ctrl, 'clientRMModel', $this->makeFluentStub(['user_id' => 4]));
|
|
$this->inject($ctrl, 'claimStatusModel', $this->makeFluentStub(['id' => 1]));
|
|
|
|
// nonEbTicketModel->first() returns existing row => duplicate detected
|
|
$this->inject($ctrl, 'nonEbTicketModel', $this->makeFluentStub(['id' => 550]));
|
|
|
|
$resp = $ctrl->createClaim();
|
|
|
|
$this->assertSame(409, $resp->getStatusCode());
|
|
$body = $this->body($resp);
|
|
print_r($body);
|
|
$this->assertFalse($body['status']);
|
|
$this->assertSame(409, $body['code']);
|
|
$this->assertStringContainsString('Duplicate', $body['message']);
|
|
}
|
|
|
|
public function testReturns200AndClaimIdOnSuccess(): void
|
|
{
|
|
$_POST = [
|
|
'client_policy_id' => 10,
|
|
'nature_of_loss' => 'Storm damage',
|
|
'loss_location' => 'Hyderabad',
|
|
'loss_date' => '15-03-2026',
|
|
];
|
|
|
|
$ctrl = $this->makeController(['id' => 1, 'name' => 'Test User', 'email' => 'u@t.com', 'mobile' => '9876543210']);
|
|
|
|
$this->inject($ctrl, 'clientPolicyModel', $this->makeFluentStub([
|
|
'id' => 10,
|
|
'client_id' => 5,
|
|
'client_branch_id' => 2,
|
|
'policy_type_id' => 10,
|
|
'insurer_id' => 7,
|
|
'policy_no' => 'POL/2026/STR',
|
|
]));
|
|
$this->inject($ctrl, 'policyTypeModel', $this->makeFluentStub(['allocg' => 'Marine']));
|
|
$this->inject($ctrl, 'clientRMModel', $this->makeFluentStub(['user_id' => 4]));
|
|
$this->inject($ctrl, 'claimStatusModel', $this->makeFluentStub(['id' => 1]));
|
|
|
|
// nonEbTicketModel: first() returns null (no duplicate), insert() returns 99
|
|
$ticketStub = new class {
|
|
private int $callCount = 0;
|
|
public function __call(string $name, array $args): mixed
|
|
{
|
|
if ($name === 'first') return null; // no duplicate
|
|
if ($name === 'insert') return 99;
|
|
if ($name === 'insertID') return 99;
|
|
return $this;
|
|
}
|
|
};
|
|
$this->inject($ctrl, 'nonEbTicketModel', $ticketStub);
|
|
|
|
// Provide pass-through stubs for asset and history models
|
|
$noopStub = new class {
|
|
public function __call(string $n, array $a): mixed { return $this; }
|
|
};
|
|
$this->inject($ctrl, 'assetModel', $noopStub);
|
|
$this->inject($ctrl, 'ticketHistoryModel', $noopStub);
|
|
|
|
$resp = $ctrl->createClaim();
|
|
|
|
$this->assertSame(200, $resp->getStatusCode());
|
|
$body = $this->body($resp);
|
|
print_r($body);
|
|
$this->assertTrue($body['status']);
|
|
$this->assertSame(200, $body['code']);
|
|
$this->assertSame(99, $body['claim_id']);
|
|
$this->assertStringContainsString('created', strtolower($body['message']));
|
|
}
|
|
}
|