181 lines
5.3 KiB
PHP
181 lines
5.3 KiB
PHP
<?php
|
|
|
|
namespace Tests\App\Controllers\Api;
|
|
|
|
use App\Controllers\Api\BroadcastEmailController;
|
|
use CodeIgniter\HTTP\ResponseInterface;
|
|
use CodeIgniter\HTTP\URI;
|
|
use CodeIgniter\HTTP\UserAgent;
|
|
use CodeIgniter\Test\CIUnitTestCase;
|
|
use CodeIgniter\Test\Mock\MockIncomingRequest;
|
|
use Config\App;
|
|
|
|
class FakeBroadcastRequest extends MockIncomingRequest
|
|
{
|
|
public function __construct(private readonly ?array $json = null)
|
|
{
|
|
parent::__construct(config(App::class), new URI('https://test.alrahmaisgl.org'), 'php://input', new UserAgent());
|
|
}
|
|
|
|
public function getJSON(bool $assoc = false, int $depth = 512, int $options = 0): ?array
|
|
{
|
|
return $this->json;
|
|
}
|
|
}
|
|
|
|
class StubBroadcastModel
|
|
{
|
|
public array $inserted = [];
|
|
|
|
public function insert(array $data)
|
|
{
|
|
$this->inserted[] = $data;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
class StubUserModel
|
|
{
|
|
public function __construct(private readonly array $parents = [])
|
|
{
|
|
}
|
|
|
|
public function select($columns)
|
|
{
|
|
return $this;
|
|
}
|
|
|
|
public function join(...$args)
|
|
{
|
|
return $this;
|
|
}
|
|
|
|
public function where(...$args)
|
|
{
|
|
return $this;
|
|
}
|
|
|
|
public function findAll(): array
|
|
{
|
|
return $this->parents;
|
|
}
|
|
}
|
|
|
|
class TestableBroadcastEmailController extends BroadcastEmailController
|
|
{
|
|
public bool $validationResult = true;
|
|
public array $validationErrors = [];
|
|
public $validator;
|
|
|
|
public function __construct()
|
|
{
|
|
// keep the parent constructor from running to avoid real models
|
|
}
|
|
|
|
public function setBroadcastModel(StubBroadcastModel $model): void
|
|
{
|
|
$this->broadcastModel = $model;
|
|
}
|
|
|
|
public function setUserModel(StubUserModel $model): void
|
|
{
|
|
$this->userModel = $model;
|
|
}
|
|
|
|
public function setValidationResult(bool $result, array $errors = []): void
|
|
{
|
|
$this->validationResult = $result;
|
|
$this->validationErrors = $errors;
|
|
}
|
|
|
|
protected function validate($rules, array $messages = []): bool
|
|
{
|
|
$this->validator = new class($this->validationErrors) {
|
|
public function __construct(private readonly array $errors)
|
|
{
|
|
}
|
|
|
|
public function getErrors(): array
|
|
{
|
|
return $this->errors;
|
|
}
|
|
};
|
|
|
|
return $this->validationResult;
|
|
}
|
|
|
|
protected function respondSuccess($data = null, string $message = 'Success', int $code = ResponseInterface::HTTP_OK)
|
|
{
|
|
return ['status' => true, 'message' => $message, 'data' => $data, 'code' => $code];
|
|
}
|
|
|
|
protected function respondValidationError(array $errors, string $message = 'Validation failed')
|
|
{
|
|
return ['status' => false, 'message' => $message, 'errors' => $errors, 'code' => ResponseInterface::HTTP_UNPROCESSABLE_ENTITY];
|
|
}
|
|
}
|
|
|
|
class BroadcastEmailControllerTest extends CIUnitTestCase
|
|
{
|
|
private TestableBroadcastEmailController $controller;
|
|
private StubBroadcastModel $broadcastModel;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
$this->controller = new TestableBroadcastEmailController();
|
|
$this->broadcastModel = new StubBroadcastModel();
|
|
$this->controller->setBroadcastModel($this->broadcastModel);
|
|
}
|
|
|
|
public function testSendValidationFails(): void
|
|
{
|
|
$this->controller->setValidationResult(false, ['subject' => 'required']);
|
|
$this->controller->setRequest(new FakeBroadcastRequest(['subject' => '', 'body' => '', 'recipients' => []]));
|
|
|
|
$response = $this->controller->send();
|
|
|
|
$this->assertSame(ResponseInterface::HTTP_UNPROCESSABLE_ENTITY, $response['code']);
|
|
$this->assertSame('Validation failed', $response['message']);
|
|
$this->assertArrayHasKey('subject', $response['errors']);
|
|
}
|
|
|
|
public function testSendStoresSentAndFailedRecipients(): void
|
|
{
|
|
$requestData = [
|
|
'subject' => 'Weekly Update',
|
|
'body' => 'Hello parents',
|
|
'recipients' => ['parent1@example.com', 'bad-email'],
|
|
];
|
|
$this->controller->setRequest(new FakeBroadcastRequest($requestData));
|
|
|
|
$response = $this->controller->send();
|
|
|
|
$this->assertSame(ResponseInterface::HTTP_OK, $response['code']);
|
|
$this->assertSame('Broadcast email sent successfully', $response['message']);
|
|
$this->assertSame(['parent1@example.com'], $response['data']['sent']);
|
|
$this->assertSame(['bad-email'], $response['data']['failed']);
|
|
$this->assertCount(1, $this->broadcastModel->inserted);
|
|
$data = $this->broadcastModel->inserted[0];
|
|
$this->assertSame('Weekly Update', $data['subject']);
|
|
$this->assertSame('Hello parents', $data['body']);
|
|
$this->assertSame(1, $data['total_sent']);
|
|
$this->assertArrayHasKey('created_at', $data);
|
|
}
|
|
|
|
public function testParentsReturnsParentList(): void
|
|
{
|
|
$parents = [
|
|
['id' => 10, 'firstname' => 'Test', 'lastname' => 'Parent', 'email' => 'test@parent.com'],
|
|
];
|
|
$this->controller->setUserModel(new StubUserModel($parents));
|
|
|
|
$response = $this->controller->parents();
|
|
|
|
$this->assertSame(ResponseInterface::HTTP_OK, $response['code']);
|
|
$this->assertSame('Parent list retrieved successfully', $response['message']);
|
|
$this->assertSame($parents, $response['data']);
|
|
}
|
|
}
|