Skip to content

Commit 8a4a09b

Browse files
committed
More tests
1 parent d889701 commit 8a4a09b

File tree

9 files changed

+360
-54
lines changed

9 files changed

+360
-54
lines changed

src/Handler/Delete.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ public function handle(Request $request): Response
3232

3333
run_callbacks($schema->getListeners('deleting'), [$this->model, $request]);
3434

35-
$this->resource->getAdapter()->delete($this->model);
35+
if ($deleter = $this->resource->getSchema()->getDelete()) {
36+
$deleter($this->model, $request);
37+
} else {
38+
$this->resource->getAdapter()->delete($this->model);
39+
}
3640

3741
run_callbacks($schema->getListeners('deleted'), [$this->model, $request]);
3842

tests/AbstractTestCase.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
1515
use PHPUnit\Framework\TestCase;
16-
use Psr\Http\Message\ResponseInterface;
1716
use Zend\Diactoros\ServerRequest;
1817
use Zend\Diactoros\Uri;
1918

tests/MockAdapter.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Tobyz\Tests\JsonApiServer;
44

5+
use Closure;
56
use Tobyz\JsonApiServer\Adapter\AdapterInterface;
67
use Tobyz\JsonApiServer\Schema\Attribute;
78
use Tobyz\JsonApiServer\Schema\Field;
@@ -52,12 +53,12 @@ public function getAttribute($model, Attribute $attribute)
5253
return $model->{$this->getProperty($attribute)} ?? 'default';
5354
}
5455

55-
public function getHasOne($model, HasOne $relationship)
56+
public function getHasOne($model, HasOne $relationship, array $fields = null)
5657
{
5758
return $model->{$this->getProperty($relationship)} ?? null;
5859
}
5960

60-
public function getHasMany($model, HasMany $relationship): array
61+
public function getHasMany($model, HasMany $relationship, array $fields = null): array
6162
{
6263
return $model->{$this->getProperty($relationship)} ?? [];
6364
}
@@ -121,7 +122,7 @@ public function paginate($query, int $limit, int $offset): void
121122
$query->paginate[] = [$limit, $offset];
122123
}
123124

124-
public function load(array $models, array $relationships): void
125+
public function load(array $models, array $relationships, Closure $scope): void
125126
{
126127
foreach ($models as $model) {
127128
$model->load[] = $relationships;

tests/feature/CountabilityTest.php

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Tobyz\Tests\JsonApiServer\feature;
1313

1414
use Tobyz\JsonApiServer\JsonApi;
15+
use Tobyz\JsonApiServer\Schema\Type;
1516
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
1617
use Tobyz\Tests\JsonApiServer\MockAdapter;
1718

@@ -31,21 +32,58 @@ public function setUp(): void
3132
{
3233
$this->api = new JsonApi('http://example.com');
3334

34-
$this->adapter = new MockAdapter();
35+
$models = [];
36+
for ($i = 1; $i <= 100; $i++) {
37+
$models[] = (object) ['type' => 'users', 'id' => $i];
38+
}
39+
40+
$this->adapter = new MockAdapter($models, 'users');
3541
}
3642

3743
public function test_total_number_of_resources_and_last_pagination_link_is_included_by_default()
3844
{
39-
$this->markTestIncomplete();
45+
$this->api->resource('users', $this->adapter);
46+
47+
$response = $this->api->handle(
48+
$this->buildRequest('GET', '/users')
49+
);
50+
51+
$document = json_decode($response->getBody(), true);
52+
53+
$this->assertArrayHasKey('last', $document['links'] ?? []);
54+
$this->assertEquals(100, $document['meta']['total'] ?? null);
4055
}
4156

4257
public function test_types_can_be_made_uncountable()
4358
{
44-
$this->markTestIncomplete();
59+
$this->api->resource('users', $this->adapter, function (Type $type) {
60+
$type->uncountable();
61+
});
62+
63+
$response = $this->api->handle(
64+
$this->buildRequest('GET', '/users')
65+
);
66+
67+
$document = json_decode($response->getBody(), true);
68+
69+
$this->assertArrayNotHasKey('last', $document['links'] ?? []);
70+
$this->assertArrayNotHasKey('total', $document['meta'] ?? []);
4571
}
4672

4773
public function test_types_can_be_made_countable()
4874
{
49-
$this->markTestIncomplete();
75+
$this->api->resource('users', $this->adapter, function (Type $type) {
76+
$type->uncountable();
77+
$type->countable();
78+
});
79+
80+
$response = $this->api->handle(
81+
$this->buildRequest('GET', '/users')
82+
);
83+
84+
$document = json_decode($response->getBody(), true);
85+
86+
$this->assertArrayHasKey('last', $document['links'] ?? []);
87+
$this->assertEquals(100, $document['meta']['total'] ?? null);
5088
}
5189
}

tests/feature/CreateTest.php

Lines changed: 145 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@
1111

1212
namespace Tobyz\Tests\JsonApiServer\feature;
1313

14+
use Psr\Http\Message\ServerRequestInterface;
15+
use Tobyz\JsonApiServer\Adapter\AdapterInterface;
16+
use Tobyz\JsonApiServer\Exception\ForbiddenException;
1417
use Tobyz\JsonApiServer\JsonApi;
18+
use Tobyz\JsonApiServer\Schema\Type;
1519
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
1620
use Tobyz\Tests\JsonApiServer\MockAdapter;
1721

@@ -22,58 +26,181 @@ class CreateTest extends AbstractTestCase
2226
*/
2327
private $api;
2428

25-
/**
26-
* @var MockAdapter
27-
*/
28-
private $adapter;
29-
3029
public function setUp(): void
3130
{
3231
$this->api = new JsonApi('http://example.com');
32+
}
3333

34-
$this->adapter = new MockAdapter();
34+
protected function createResource(array $data = [])
35+
{
36+
return $this->api->handle(
37+
$this->buildRequest('POST', '/users')
38+
->withParsedBody([
39+
'data' => array_merge([
40+
'type' => 'users',
41+
'id' => '1',
42+
], $data)
43+
])
44+
);
3545
}
3646

3747
public function test_resources_are_not_creatable_by_default()
3848
{
39-
$this->markTestIncomplete();
49+
$this->api->resource('users', new MockAdapter());
50+
51+
$this->expectException(ForbiddenException::class);
52+
53+
$this->createResource();
4054
}
4155

4256
public function test_resource_creation_can_be_explicitly_enabled()
4357
{
44-
$this->markTestIncomplete();
58+
$this->api->resource('users', new MockAdapter(), function (Type $type) {
59+
$type->creatable();
60+
});
61+
62+
$response = $this->createResource();
63+
64+
$this->assertEquals(201, $response->getStatusCode());
4565
}
4666

4767
public function test_resource_creation_can_be_conditionally_enabled()
4868
{
49-
$this->markTestIncomplete();
69+
$this->api->resource('users', new MockAdapter(), function (Type $type) {
70+
$type->creatable(function () {
71+
return true;
72+
});
73+
});
74+
75+
$response = $this->createResource();
76+
77+
$this->assertEquals(201, $response->getStatusCode());
5078
}
5179

5280
public function test_resource_creation_can_be_explicitly_disabled()
5381
{
54-
$this->markTestIncomplete();
82+
$this->api->resource('users', new MockAdapter(), function (Type $type) {
83+
$type->notCreatable();
84+
});
85+
86+
$this->expectException(ForbiddenException::class);
87+
88+
$this->createResource();
5589
}
5690

5791
public function test_resource_creation_can_be_conditionally_disabled()
5892
{
59-
$this->markTestIncomplete();
93+
$this->api->resource('users', new MockAdapter(), function (Type $type) {
94+
$type->creatable(function () {
95+
return false;
96+
});
97+
});
98+
99+
$this->expectException(ForbiddenException::class);
100+
101+
$this->createResource();
102+
}
103+
104+
public function test_resource_creatable_callback_receives_correct_parameters()
105+
{
106+
$called = false;
107+
108+
$this->api->resource('users', new MockAdapter(), function (Type $type) use (&$called) {
109+
$type->creatable(function ($request) use (&$called) {
110+
$this->assertInstanceOf(ServerRequestInterface::class, $request);
111+
return $called = true;
112+
});
113+
});
114+
115+
$this->createResource();
116+
117+
$this->assertTrue($called);
60118
}
61119

62-
public function test_new_models_are_supplied_by_the_adapter()
120+
public function test_new_models_are_supplied_and_saved_by_the_adapter()
63121
{
64-
$this->markTestIncomplete();
122+
$adapter = $this->prophesize(AdapterInterface::class);
123+
$adapter->create()->willReturn($createdModel = (object) []);
124+
$adapter->save($createdModel)->shouldBeCalled();
125+
$adapter->getId($createdModel)->willReturn('1');
126+
127+
$this->api->resource('users', $adapter->reveal(), function (Type $type) {
128+
$type->creatable();
129+
});
130+
131+
$this->createResource();
65132
}
66133

67134
public function test_resources_can_provide_custom_models()
68135
{
69-
$this->markTestIncomplete();
136+
$createdModel = (object) [];
137+
138+
$adapter = $this->prophesize(AdapterInterface::class);
139+
$adapter->create()->shouldNotBeCalled();
140+
$adapter->save($createdModel)->shouldBeCalled();
141+
$adapter->getId($createdModel)->willReturn('1');
142+
143+
$this->api->resource('users', $adapter->reveal(), function (Type $type) use ($createdModel) {
144+
$type->creatable();
145+
$type->create(function ($request) use ($createdModel) {
146+
$this->assertInstanceOf(ServerRequestInterface::class, $request);
147+
return $createdModel;
148+
});
149+
});
150+
151+
$this->createResource();
70152
}
71153

72-
public function test_creating_a_resource_calls_the_save_adapter_method()
154+
public function test_resources_can_provide_custom_savers()
73155
{
74-
$this->markTestIncomplete();
156+
$called = false;
157+
158+
$adapter = $this->prophesize(AdapterInterface::class);
159+
$adapter->create()->willReturn($createdModel = (object) []);
160+
$adapter->save($createdModel)->shouldNotBeCalled();
161+
$adapter->getId($createdModel)->willReturn('1');
162+
163+
$this->api->resource('users', $adapter->reveal(), function (Type $type) use ($createdModel, &$called) {
164+
$type->creatable();
165+
$type->save(function ($model, $request) use ($createdModel, &$called) {
166+
$model->id = '1';
167+
$this->assertSame($createdModel, $model);
168+
$this->assertInstanceOf(ServerRequestInterface::class, $request);
169+
return $called = true;
170+
});
171+
});
172+
173+
$this->createResource();
174+
175+
$this->assertTrue($called);
75176
}
76177

77-
// saver...
78-
// listeners...
178+
public function test_resources_can_have_creation_listeners()
179+
{
180+
$called = 0;
181+
182+
$adapter = $this->prophesize(AdapterInterface::class);
183+
$adapter->create()->willReturn($createdModel = (object) []);
184+
$adapter->getId($createdModel)->willReturn('1');
185+
186+
$this->api->resource('users', $adapter->reveal(), function (Type $type) use ($adapter, $createdModel, &$called) {
187+
$type->creatable();
188+
$type->creating(function ($model, $request) use ($adapter, $createdModel, &$called) {
189+
$this->assertSame($createdModel, $model);
190+
$this->assertInstanceOf(ServerRequestInterface::class, $request);
191+
$adapter->save($createdModel)->shouldNotHaveBeenCalled();
192+
$called++;
193+
});
194+
$type->created(function ($model, $request) use ($adapter, $createdModel, &$called) {
195+
$this->assertSame($createdModel, $model);
196+
$this->assertInstanceOf(ServerRequestInterface::class, $request);
197+
$adapter->save($createdModel)->shouldHaveBeenCalled();
198+
$called++;
199+
});
200+
});
201+
202+
$this->createResource();
203+
204+
$this->assertEquals(2, $called);
205+
}
79206
}

0 commit comments

Comments
 (0)