recreate project
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
<?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']);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user