Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions app/Dtos/PostRequestDto.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace App\Dtos;

use Infra\Interfaces\RequestDtoInterface;

class PostRequestDto implements RequestDtoInterface
{
public function __construct(
public string $title,
public ?string $content = '',
) {}

/**
* @param string[] $data
*/
public static function fromRequestData(array $data): self
{
$title = $data['title'] ?? '';

$content = $data['content'] ?? '';

return new self($title, $content);
}
}
3 changes: 2 additions & 1 deletion app/Handlers/Api/PostHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace App\Handlers\Api;

use App\Dtos\PostRequestDto;
use Infra\Http\Request;
use Infra\Http\Response;
use Infra\Interfaces\RequestHandlerInterface;
Expand All @@ -13,7 +14,7 @@ class PostHandler implements RequestHandlerInterface
public function handle(Request $request): Response
{
return Response::json([
'data' => $request->getData(),
'data' => $request->getData(PostRequestDto::class),
'params' => $request->getParams(),
]);
}
Expand Down
28 changes: 11 additions & 17 deletions infra/Http/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Infra\Http;

use Infra\Enums\HttpMethod;
use Infra\Interfaces\RequestDtoInterface;
use RuntimeException;

class Request
Expand Down Expand Up @@ -95,25 +96,18 @@ private static function getHeadersFromGlobals(): array
return $headers;
}

public function int(string $field): int
{
return (int) $this->__get($field);
}

public function bool(string $field): bool
{
return (bool) $this->__get($field);
}

public function __get(string $field): string
/**
* @template T of RequestDtoInterface
*
* @param class-string<T> $requestDto
* @return T
*/
public function getData(string $requestDto): RequestDtoInterface
{
return $this->data[$field] ?? '';
}
/** @var T $requestData */
$requestData = $requestDto::fromRequestData($this->data);

/** @return string[] */
public function getData(): array
{
return $this->data;
return $requestData;
}

public function getPath(): string
Expand Down
11 changes: 11 additions & 0 deletions infra/Interfaces/RequestDtoInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Infra\Interfaces;

interface RequestDtoInterface
{
/**
* @param string[] $data
*/
public static function fromRequestData(array $data): self;
}
5 changes: 4 additions & 1 deletion tests/Unit/app/Handlers/PostHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@

describe('Api', function () {
it('should return a json response', function () {
$data = ['test' => 'data'];
$data = [
'title' => 'Test title',
'content' => 'Test content',
];
$params = ['id' => 1.1];

$request = new Request("/api/posts/{$params['id']}", HttpMethod::POST, $data);
Expand Down
36 changes: 0 additions & 36 deletions tests/Unit/infra/Http/RequestTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,42 +38,6 @@
});
});

describe('Data Handling', function () {
beforeEach(function () {
$this->data = [
'name' => 'John Doe',
'age' => '30',
'active' => 'true',
];

$this->request = prepareRequest(data: $this->data);
});

it('should access request data as properties', function () {
expect($this->request->name)
->toBeString()
->toBe('John Doe');
});

it('should convert a data field to an integer', function () {
expect($this->request->int('age'))
->toBeInt()
->toBe(30);
});

it('should convert a data field to a boolean', function () {
expect($this->request->bool('active'))
->toBeBool()
->toBeTrue();
});

it('should return all data as an array', function () {
expect($this->request->getData())
->toBeArray()
->toBe($this->data);
});
});

describe('Getters', function () {
it('should return the correct request path', function () {
$request = prepareRequest(path: '/users/1');
Expand Down