diff --git a/.gitignore b/.gitignore index 81d7cc9..6cadeca 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,6 @@ psalm.xml testbench.yaml /docs /coverage + +# OS +.DS_Store diff --git a/src/Data/Project.php b/src/Data/Project.php new file mode 100644 index 0000000..c2e5ba6 --- /dev/null +++ b/src/Data/Project.php @@ -0,0 +1,23 @@ +uuid}/"; } + + public function createDtoFromResponse(Response $response): Project + { + return Project::fromResponse($response->json('data.object')); + } } diff --git a/src/Requests/Projects/GetProjectsRequest.php b/src/Requests/Projects/GetProjectsRequest.php index 34ffecb..4352d4e 100644 --- a/src/Requests/Projects/GetProjectsRequest.php +++ b/src/Requests/Projects/GetProjectsRequest.php @@ -2,8 +2,10 @@ namespace NieuwbouwOffice\PhpSdk\Requests\Projects; +use NieuwbouwOffice\PhpSdk\Data\Project; use Saloon\Enums\Method; use Saloon\Http\Request; +use Saloon\Http\Response; class GetProjectsRequest extends Request { @@ -13,4 +15,15 @@ public function resolveEndpoint(): string { return '/projects/'; } + + /** + * @return Project[] + */ + public function createDtoFromResponse(Response $response): array + { + return array_map( + fn (array $object) => Project::fromResponse($object), + $response->json('data.objects'), + ); + } } diff --git a/src/Resources/ProjectResource.php b/src/Resources/ProjectResource.php index 2de15a7..f98ded3 100644 --- a/src/Resources/ProjectResource.php +++ b/src/Resources/ProjectResource.php @@ -2,20 +2,23 @@ namespace NieuwbouwOffice\PhpSdk\Resources; +use NieuwbouwOffice\PhpSdk\Data\Project; use NieuwbouwOffice\PhpSdk\Requests\Projects\GetProjectRequest; use NieuwbouwOffice\PhpSdk\Requests\Projects\GetProjectsRequest; use Saloon\Http\BaseResource; -use Saloon\Http\Response; class ProjectResource extends BaseResource { - public function list(): Response + /** + * @return Project[] + */ + public function list(): array { - return $this->connector->send(new GetProjectsRequest); + return $this->connector->send(new GetProjectsRequest)->dto(); } - public function get(string $uuid): Response + public function get(string $uuid): Project { - return $this->connector->send(new GetProjectRequest($uuid)); + return $this->connector->send(new GetProjectRequest($uuid))->dto(); } } diff --git a/tests/Data/ProjectTest.php b/tests/Data/ProjectTest.php new file mode 100644 index 0000000..f6b359e --- /dev/null +++ b/tests/Data/ProjectTest.php @@ -0,0 +1,17 @@ +uuid)->toBe('abc-123') + ->and($project->title)->toBe('Project ABC') + ->and($project->created_at)->toBe('2026-01-01T00:00:00Z') + ->and($project->updated_at)->toBe('2026-02-01T00:00:00Z'); +}); diff --git a/tests/Requests/Projects/GetProjectRequestTest.php b/tests/Requests/Projects/GetProjectRequestTest.php index e4c0e55..240af64 100644 --- a/tests/Requests/Projects/GetProjectRequestTest.php +++ b/tests/Requests/Projects/GetProjectRequestTest.php @@ -1,7 +1,11 @@ getMethod())->toBe(Method::GET); @@ -15,3 +19,28 @@ expect((new GetProjectRequest('abc-123'))->resolveEndpoint()) ->toBe('/projects/abc-123/'); }); + +it('creates a Project DTO from the response', function () { + $mockClient = new MockClient([ + GetProjectRequest::class => MockResponse::make([ + 'data' => [ + 'object' => [ + 'Project_UUId' => 'e00afb7a1791a22eb8bca3707687c549', + 'Project_Titel' => 'De Suikerzijde', + 'Project_Timestamp' => '2025-12-02 14:43:53', + ], + ], + ]), + ]); + + $connector = new NieuwbouwOffice('test-token'); + $connector->withMockClient($mockClient); + + $project = $connector->send(new GetProjectRequest('e00afb7a1791a22eb8bca3707687c549'))->dto(); + + expect($project)->toBeInstanceOf(Project::class) + ->and($project->uuid)->toBe('e00afb7a1791a22eb8bca3707687c549') + ->and($project->title)->toBe('De Suikerzijde') + ->and($project->created_at)->toBe('2025-12-02 14:43:53') + ->and($project->updated_at)->toBe('2025-12-02 14:43:53'); +}); diff --git a/tests/Requests/Projects/GetProjectsRequestTest.php b/tests/Requests/Projects/GetProjectsRequestTest.php index 5189c59..045bb3f 100644 --- a/tests/Requests/Projects/GetProjectsRequestTest.php +++ b/tests/Requests/Projects/GetProjectsRequestTest.php @@ -1,7 +1,11 @@ getMethod())->toBe(Method::GET); @@ -10,3 +14,44 @@ it('resolves to the /projects/ endpoint', function () { expect((new GetProjectsRequest)->resolveEndpoint())->toBe('/projects/'); }); + +it('creates an array of Project DTOs from the response', function () { + $mockClient = new MockClient([ + GetProjectsRequest::class => MockResponse::make([ + 'data' => [ + 'objects' => [ + [ + 'Project_UUId' => 'e00afb7a1791a22eb8bca3707687c549', + 'Project_Titel' => 'De Suikerzijde', + 'Project_Timestamp' => '2025-12-02 14:43:53', + 'Laatst_Bijgewerkt' => '2025-12-02 14:43:53', + ], + [ + 'Project_UUId' => 'e51d280c47f8ed8b780adfc1bb25436a', + 'Project_Titel' => 'Suikerzijde - Hanny van den Horsthof', + 'Project_Timestamp' => '2025-06-12 16:53:48', + 'Laatst_Bijgewerkt' => '2026-05-07 08:47:23', + ], + ], + ], + 'meta' => ['count' => 2], + ]), + ]); + + $connector = new NieuwbouwOffice('test-token'); + $connector->withMockClient($mockClient); + + $projects = $connector->send(new GetProjectsRequest)->dto(); + + expect($projects)->toBeArray()->toHaveCount(2) + ->and($projects[0])->toBeInstanceOf(Project::class) + ->and($projects[0]->uuid)->toBe('e00afb7a1791a22eb8bca3707687c549') + ->and($projects[0]->title)->toBe('De Suikerzijde') + ->and($projects[0]->created_at)->toBe('2025-12-02 14:43:53') + ->and($projects[0]->updated_at)->toBe('2025-12-02 14:43:53') + ->and($projects[1])->toBeInstanceOf(Project::class) + ->and($projects[1]->uuid)->toBe('e51d280c47f8ed8b780adfc1bb25436a') + ->and($projects[1]->title)->toBe('Suikerzijde - Hanny van den Horsthof') + ->and($projects[1]->created_at)->toBe('2025-06-12 16:53:48') + ->and($projects[1]->updated_at)->toBe('2026-05-07 08:47:23'); +}); diff --git a/tests/Resources/ProjectResourceTest.php b/tests/Resources/ProjectResourceTest.php index af6713f..315c896 100644 --- a/tests/Resources/ProjectResourceTest.php +++ b/tests/Resources/ProjectResourceTest.php @@ -1,57 +1,70 @@ MockResponse::make([ 'data' => [ - ['uuid' => 'a', 'name' => 'Project A'], - ['uuid' => 'b', 'name' => 'Project B'], + 'objects' => [ + [ + 'Project_UUId' => 'a', + 'Project_Titel' => 'Project A', + 'Project_Timestamp' => '2025-12-02 14:43:53', + 'Laatst_Bijgewerkt' => '2025-12-02 14:43:53', + ], + [ + 'Project_UUId' => 'b', + 'Project_Titel' => 'Project B', + 'Project_Timestamp' => '2025-06-12 16:53:48', + 'Laatst_Bijgewerkt' => '2026-05-07 08:47:23', + ], + ], ], + 'meta' => ['count' => 2], ]), ]); $connector = new NieuwbouwOffice('test-token'); $connector->withMockClient($mockClient); - $response = $connector->projects()->list(); + $projects = $connector->projects()->list(); - expect($response)->toBeInstanceOf(Response::class) - ->and($response->json())->toBe([ - 'data' => [ - ['uuid' => 'a', 'name' => 'Project A'], - ['uuid' => 'b', 'name' => 'Project B'], - ], - ]); + expect($projects)->toBeArray()->toHaveCount(2) + ->and($projects[0])->toBeInstanceOf(Project::class) + ->and($projects[0]->uuid)->toBe('a') + ->and($projects[1]->uuid)->toBe('b'); $mockClient->assertSent(GetProjectsRequest::class); }); -it('get() sends a GetProjectRequest with the given uuid and returns the response', function () { +it('get() sends a GetProjectRequest with the given uuid and returns a Project DTO', function () { $mockClient = new MockClient([ GetProjectRequest::class => MockResponse::make([ - 'uuid' => 'abc-123', - 'name' => 'Project ABC', + 'data' => [ + 'object' => [ + 'Project_UUId' => 'abc-123', + 'Project_Titel' => 'Project ABC', + 'Project_Timestamp' => '2025-12-02 14:43:53', + ], + ], ]), ]); $connector = new NieuwbouwOffice('test-token'); $connector->withMockClient($mockClient); - $response = $connector->projects()->get('abc-123'); + $project = $connector->projects()->get('abc-123'); - expect($response)->toBeInstanceOf(Response::class) - ->and($response->json())->toBe([ - 'uuid' => 'abc-123', - 'name' => 'Project ABC', - ]); + expect($project)->toBeInstanceOf(Project::class) + ->and($project->uuid)->toBe('abc-123') + ->and($project->title)->toBe('Project ABC'); $mockClient->assertSent(function ($request) { return $request instanceof GetProjectRequest