From c03b917ad6077d3ba31a104944fb7b28e98235ed Mon Sep 17 00:00:00 2001 From: Jan Henk Hazelaar Date: Tue, 5 May 2026 16:29:00 +0200 Subject: [PATCH 1/2] Add ProjectResource with list and get Introduce a ProjectResource on the connector exposing list() and get(uuid) that dispatch GetProjectsRequest and GetProjectRequest respectively. The requests live under Requests/Projects and target /projects/ and /projects/{uuid}/. Cover the new code with focused request tests and MockClient-backed resource tests. --- src/NieuwbouwOffice.php | 6 ++ src/Requests/Projects/GetProjectRequest.php | 18 +++++ src/Requests/Projects/GetProjectsRequest.php | 16 +++++ src/Resources/ProjectResource.php | 21 ++++++ tests/NieuwbouwOfficeTest.php | 7 ++ .../Projects/GetProjectRequestTest.php | 17 +++++ .../Projects/GetProjectsRequestTest.php | 12 ++++ tests/Resources/ProjectResourceTest.php | 67 +++++++++++++++++++ 8 files changed, 164 insertions(+) create mode 100644 src/Requests/Projects/GetProjectRequest.php create mode 100644 src/Requests/Projects/GetProjectsRequest.php create mode 100644 src/Resources/ProjectResource.php create mode 100644 tests/Requests/Projects/GetProjectRequestTest.php create mode 100644 tests/Requests/Projects/GetProjectsRequestTest.php create mode 100644 tests/Resources/ProjectResourceTest.php diff --git a/src/NieuwbouwOffice.php b/src/NieuwbouwOffice.php index 4e1c134..8c9afd4 100755 --- a/src/NieuwbouwOffice.php +++ b/src/NieuwbouwOffice.php @@ -2,6 +2,7 @@ namespace NieuwbouwOffice\PhpSdk; +use NieuwbouwOffice\PhpSdk\Resources\ProjectResource; use Saloon\Http\Auth\TokenAuthenticator; use Saloon\Http\Connector; use Saloon\Traits\Plugins\AcceptsJson; @@ -26,4 +27,9 @@ protected function defaultAuth(): TokenAuthenticator { return new TokenAuthenticator($this->token, 'apikey'); } + + public function projects(): ProjectResource + { + return new ProjectResource($this); + } } diff --git a/src/Requests/Projects/GetProjectRequest.php b/src/Requests/Projects/GetProjectRequest.php new file mode 100644 index 0000000..e107b81 --- /dev/null +++ b/src/Requests/Projects/GetProjectRequest.php @@ -0,0 +1,18 @@ +uuid}/"; + } +} diff --git a/src/Requests/Projects/GetProjectsRequest.php b/src/Requests/Projects/GetProjectsRequest.php new file mode 100644 index 0000000..34ffecb --- /dev/null +++ b/src/Requests/Projects/GetProjectsRequest.php @@ -0,0 +1,16 @@ +connector->send(new GetProjectsRequest()); + } + + public function get(string $uuid): Response + { + return $this->connector->send(new GetProjectRequest($uuid)); + } +} diff --git a/tests/NieuwbouwOfficeTest.php b/tests/NieuwbouwOfficeTest.php index 5db9645..6553d82 100644 --- a/tests/NieuwbouwOfficeTest.php +++ b/tests/NieuwbouwOfficeTest.php @@ -1,6 +1,7 @@ headers()->get('Accept'))->toBe('application/json'); }); + +it('exposes the projects resource', function () { + $connector = new NieuwbouwOffice('test-token'); + + expect($connector->projects())->toBeInstanceOf(ProjectResource::class); +}); diff --git a/tests/Requests/Projects/GetProjectRequestTest.php b/tests/Requests/Projects/GetProjectRequestTest.php new file mode 100644 index 0000000..e4c0e55 --- /dev/null +++ b/tests/Requests/Projects/GetProjectRequestTest.php @@ -0,0 +1,17 @@ +getMethod())->toBe(Method::GET); +}); + +it('stores the uuid on a public property', function () { + expect((new GetProjectRequest('abc-123'))->uuid)->toBe('abc-123'); +}); + +it('resolves to the /projects/{uuid}/ endpoint', function () { + expect((new GetProjectRequest('abc-123'))->resolveEndpoint()) + ->toBe('/projects/abc-123/'); +}); diff --git a/tests/Requests/Projects/GetProjectsRequestTest.php b/tests/Requests/Projects/GetProjectsRequestTest.php new file mode 100644 index 0000000..616db18 --- /dev/null +++ b/tests/Requests/Projects/GetProjectsRequestTest.php @@ -0,0 +1,12 @@ +getMethod())->toBe(Method::GET); +}); + +it('resolves to the /projects/ endpoint', function () { + expect((new GetProjectsRequest())->resolveEndpoint())->toBe('/projects/'); +}); diff --git a/tests/Resources/ProjectResourceTest.php b/tests/Resources/ProjectResourceTest.php new file mode 100644 index 0000000..af6713f --- /dev/null +++ b/tests/Resources/ProjectResourceTest.php @@ -0,0 +1,67 @@ + MockResponse::make([ + 'data' => [ + ['uuid' => 'a', 'name' => 'Project A'], + ['uuid' => 'b', 'name' => 'Project B'], + ], + ]), + ]); + + $connector = new NieuwbouwOffice('test-token'); + $connector->withMockClient($mockClient); + + $response = $connector->projects()->list(); + + expect($response)->toBeInstanceOf(Response::class) + ->and($response->json())->toBe([ + 'data' => [ + ['uuid' => 'a', 'name' => 'Project A'], + ['uuid' => 'b', 'name' => 'Project B'], + ], + ]); + + $mockClient->assertSent(GetProjectsRequest::class); +}); + +it('get() sends a GetProjectRequest with the given uuid and returns the response', function () { + $mockClient = new MockClient([ + GetProjectRequest::class => MockResponse::make([ + 'uuid' => 'abc-123', + 'name' => 'Project ABC', + ]), + ]); + + $connector = new NieuwbouwOffice('test-token'); + $connector->withMockClient($mockClient); + + $response = $connector->projects()->get('abc-123'); + + expect($response)->toBeInstanceOf(Response::class) + ->and($response->json())->toBe([ + 'uuid' => 'abc-123', + 'name' => 'Project ABC', + ]); + + $mockClient->assertSent(function ($request) { + return $request instanceof GetProjectRequest + && $request->uuid === 'abc-123' + && $request->resolveEndpoint() === '/projects/abc-123/'; + }); +}); + +it('can be instantiated directly with a connector', function () { + $connector = new NieuwbouwOffice('test-token'); + + expect(new ProjectResource($connector))->toBeInstanceOf(ProjectResource::class); +}); From b56da0268eb70855827eafbe93f46201399a1ac3 Mon Sep 17 00:00:00 2001 From: jhhazelaar <215711+jhhazelaar@users.noreply.github.com> Date: Tue, 5 May 2026 14:29:28 +0000 Subject: [PATCH 2/2] Fix styling --- src/Resources/ProjectResource.php | 2 +- tests/Requests/Projects/GetProjectsRequestTest.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Resources/ProjectResource.php b/src/Resources/ProjectResource.php index 3e4ae94..2de15a7 100644 --- a/src/Resources/ProjectResource.php +++ b/src/Resources/ProjectResource.php @@ -11,7 +11,7 @@ class ProjectResource extends BaseResource { public function list(): Response { - return $this->connector->send(new GetProjectsRequest()); + return $this->connector->send(new GetProjectsRequest); } public function get(string $uuid): Response diff --git a/tests/Requests/Projects/GetProjectsRequestTest.php b/tests/Requests/Projects/GetProjectsRequestTest.php index 616db18..5189c59 100644 --- a/tests/Requests/Projects/GetProjectsRequestTest.php +++ b/tests/Requests/Projects/GetProjectsRequestTest.php @@ -4,9 +4,9 @@ use Saloon\Enums\Method; it('uses the GET method', function () { - expect((new GetProjectsRequest())->getMethod())->toBe(Method::GET); + expect((new GetProjectsRequest)->getMethod())->toBe(Method::GET); }); it('resolves to the /projects/ endpoint', function () { - expect((new GetProjectsRequest())->resolveEndpoint())->toBe('/projects/'); + expect((new GetProjectsRequest)->resolveEndpoint())->toBe('/projects/'); });