This commit is contained in:
Toby Zerner 2019-08-19 12:02:30 +02:00
parent 46d5ebd2a9
commit 269207eedb
44 changed files with 1659 additions and 777 deletions

View File

@ -101,10 +101,10 @@ Define an [attribute field](https://jsonapi.org/format/#document-resource-object
$schema->attribute('firstName');
```
By default the attribute will correspond to the property on your model with the same name. (`EloquentAdapter` will `snake_case` it automatically for you.) If you'd like it to correspond to a different property, provide it as a second argument:
By default the attribute will correspond to the property on your model with the same name. (`EloquentAdapter` will `snake_case` it automatically for you.) If you'd like it to correspond to a different property, use the `property` method:
```php
$schema->attribute('firstName', 'fname');
$schema->attribute('firstName')->property('fname');
```
### Relationships
@ -122,7 +122,7 @@ By default the [resource type](https://jsonapi.org/format/#document-resource-obj
$schema->hasOne('author')->type('people');
```
Like attributes, the relationship will automatically read and write to the relation on your model with the same name. If you'd like it to correspond to a different relation, provide it as a third argument.
Like attributes, the relationship will automatically read and write to the relation on your model with the same name. If you'd like it to correspond to a different relation, use the `property` method.
#### Relationship Links
@ -315,7 +315,7 @@ $schema->attribute('firstName')
});
```
If your attribute corresponds to some other form of data storage rather than a simple property on your model, you can use the `save` method to provide a closure to be run _after_ your model is saved:
If your field corresponds to some other form of data storage rather than a simple property on your model, you can use the `save` method to provide a closure to be run _after_ your model is saved:
```php
$schema->attribute('locale')

View File

@ -74,7 +74,8 @@ class EloquentAdapter implements AdapterInterface
$relation = $this->getRelation($model, $relationship);
// If this is a belongs-to relation, we can simply return the value of
// the foreign key on the model.
// the foreign key on the model. Otherwise we will have to fetch the
// full related model and return its key.
if ($relation instanceof BelongsTo) {
return $model->{$relation->getForeignKeyName()};
}

View File

@ -7,7 +7,6 @@ use Psr\Http\Message\ServerRequestInterface as Request;
use function Tobyz\JsonApiServer\evaluate;
use Tobyz\JsonApiServer\Exception\BadRequestException;
use Tobyz\JsonApiServer\ResourceType;
use Tobyz\JsonApiServer\Schema\HasMany;
use Tobyz\JsonApiServer\Schema\Relationship;
trait IncludesData

View File

@ -8,9 +8,9 @@ class JsonApiResponse extends JsonResponse
{
public function __construct(
$data,
$status = 200,
int $status = 200,
array $headers = [],
$encodingOptions = self::DEFAULT_JSON_FLAGS
int $encodingOptions = self::DEFAULT_JSON_FLAGS
) {
$headers['content-type'] = JsonApi::CONTENT_TYPE;

View File

@ -166,6 +166,4 @@ abstract class Field
{
return $this->filterable;
}
}

View File

@ -48,12 +48,12 @@ abstract class Relationship extends Field
return $this;
}
public function notLoadable()
{
$this->loadable = false;
return $this;
}
// public function notLoadable()
// {
// $this->loadable = false;
//
// return $this;
// }
public function includable()
{

View File

@ -17,7 +17,7 @@ use Tobyz\JsonApiServer\Adapter\AdapterInterface;
use Tobyz\JsonApiServer\Schema\Attribute;
use Tobyz\JsonApiServer\Schema\Relationship;
class Serializer
final class Serializer
{
protected $api;
protected $request;

View File

@ -1,107 +0,0 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\feature;
use Psr\Http\Message\ServerRequestInterface;
use Tobyz\JsonApiServer\Exception\BadRequestException;
use Tobyz\JsonApiServer\JsonApi;
use Tobyz\JsonApiServer\Schema\Type;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
use Tobyz\Tests\JsonApiServer\MockAdapter;
class AttributeFilterableTest extends AbstractTestCase
{
/**
* @var JsonApi
*/
private $api;
/**
* @var MockAdapter
*/
private $adapter;
public function setUp(): void
{
$this->api = new JsonApi('http://example.com');
$this->adapter = new MockAdapter();
}
public function test_attributes_are_not_filterable_by_default()
{
$this->api->resource('users', $this->adapter, function (Type $type) {
$type->attribute('field');
});
$this->expectException(BadRequestException::class);
$this->api->handle(
$this->buildRequest('GET', '/users')
->withQueryParams(['filter' => ['field' => 'Toby']])
);
}
public function test_attributes_can_be_filterable()
{
$attribute = null;
$this->api->resource('users', $this->adapter, function (Type $type) use (&$attribute) {
$attribute = $type->attribute('name')->filterable();
});
$this->api->handle(
$this->buildRequest('GET', '/users')
->withQueryParams(['filter' => ['name' => 'Toby']])
);
$this->assertContains([$attribute, 'Toby'], $this->adapter->query->filter);
}
public function test_attributes_can_be_filterable_with_custom_logic()
{
$called = false;
$this->api->resource('users', $this->adapter, function (Type $type) use (&$called) {
$type->attribute('name')
->filterable(function ($query, $value, $request) use (&$called) {
$this->assertSame($this->adapter->query, $query);
$this->assertEquals('Toby', $value);
$this->assertInstanceOf(ServerRequestInterface::class, $request);
$called = true;
});
});
$this->api->handle(
$this->buildRequest('GET', '/users')
->withQueryParams(['filter' => ['name' => 'Toby']])
);
$this->assertTrue($called);
$this->assertTrue(empty($this->adapter->query->filter));
}
public function test_attributes_can_be_explicitly_not_filterable()
{
$this->api->resource('users', $this->adapter, function (Type $type) {
$type->attribute('name')->notFilterable();
});
$this->expectException(BadRequestException::class);
$this->api->handle(
$this->buildRequest('GET', '/users')
->withQueryParams(['filter' => ['name' => 'Toby']])
);
}
}

View File

@ -1,393 +0,0 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\feature;
use JsonApiPhp\JsonApi\ErrorDocument;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ServerRequestInterface;
use Tobyz\JsonApiServer\ErrorProviderInterface;
use Tobyz\JsonApiServer\Exception\UnprocessableEntityException;
use Tobyz\JsonApiServer\JsonApi;
use Tobyz\JsonApiServer\Schema\Attribute;
use Tobyz\JsonApiServer\Schema\Type;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
use Tobyz\Tests\JsonApiServer\MockAdapter;
class AttributeTest extends AbstractTestCase
{
/**
* @var JsonApi
*/
private $api;
/**
* @var MockAdapter
*/
private $adapter;
public function setUp(): void
{
$this->api = new JsonApi('http://example.com');
$this->adapter = new MockAdapter([
'1' => (object) ['id' => '1', 'name' => 'Toby', 'color' => 'yellow'],
'2' => (object) ['id' => '2', 'name' => 'Franz', 'color' => 'blue'],
]);
}
public function test_multiple_attributes()
{
$this->api->resource('users', $this->adapter, function (Type $type) {
$type->attribute('name');
$type->attribute('color');
});
$response = $this->api->handle(
$this->buildRequest('GET', '/users/1')
);
$this->assertJsonApiDocumentSubset([
'data' => [
'attributes' => [
'name' => 'Toby',
'color' => 'yellow',
],
]
], $response->getBody());
}
public function test_attributes_can_specify_a_property()
{
$this->api->resource('users', $this->adapter, function (Type $type) {
$type->attribute('name')
->property('color');
});
$response = $this->api->handle(
$this->buildRequest('GET', '/users/1')
);
$this->assertJsonApiDocumentSubset([
'data' => [
'attributes' => [
'name' => 'yellow',
],
]
], $response->getBody());
}
public function test_attributes_can_have_getters()
{
$called = false;
$this->api->resource('users', $this->adapter, function (Type $type) use (&$called) {
$type->attribute('name')
->get('Toby');
$type->attribute('color')
->get(function ($model, $request) use (&$called) {
$called = true;
$this->assertSame($this->adapter->models['1'], $model);
$this->assertInstanceOf(RequestInterface::class, $request);
return 'yellow';
});
});
$response = $this->api->handle(
$this->buildRequest('GET', '/users/1')
);
$this->assertTrue($called);
$this->assertJsonApiDocumentSubset([
'data' => [
'attributes' => [
'name' => 'Toby',
'color' => 'yellow',
],
]
], $response->getBody());
}
public function test_attribute_setter_receives_correct_parameters()
{
$called = false;
$this->api->resource('users', $this->adapter, function (Type $type) use (&$called) {
$type->updatable();
$type->attribute('writable')
->writable()
->set(function ($model, $value, $request) use (&$called) {
$this->assertSame($this->adapter->models['1'], $model);
$this->assertEquals('value', $value);
$this->assertInstanceOf(RequestInterface::class, $request);
$called = true;
});
});
$this->api->handle(
$this->buildRequest('PATCH', '/users/1')
->withParsedBody([
'data' => [
'type' => 'users',
'id' => '1',
'attributes' => [
'writable' => 'value',
]
]
])
);
$this->assertTrue($called);
}
public function test_attribute_setter_precludes_adapter_action()
{
$this->api->resource('users', $this->adapter, function (Type $type) {
$type->updatable();
$type->attribute('writable')
->writable()
->set(function () {});
});
$this->api->handle(
$this->buildRequest('PATCH', '/users/1')
->withParsedBody([
'data' => [
'type' => 'users',
'id' => '1',
'attributes' => [
'writable' => 'value',
]
]
])
);
$this->assertTrue(empty($this->adapter->models['1']->writable));
}
public function test_attribute_saver_receives_correct_parameters()
{
$called = false;
$this->api->resource('users', $this->adapter, function (Type $type) use (&$called) {
$type->updatable();
$type->attribute('writable')
->writable()
->save(function ($model, $value, $request) use (&$called) {
$this->assertSame($this->adapter->models['1'], $model);
$this->assertEquals('value', $value);
$this->assertInstanceOf(RequestInterface::class, $request);
$called = true;
});
});
$this->api->handle(
$this->buildRequest('PATCH', '/users/1')
->withParsedBody([
'data' => [
'type' => 'users',
'id' => '1',
'attributes' => [
'writable' => 'value',
]
]
])
);
$this->assertTrue($called);
}
public function test_attribute_saver_precludes_adapter_action()
{
$this->api->resource('users', $this->adapter, function (Type $type) {
$type->updatable();
$type->attribute('writable')
->writable()
->save(function () {});
});
$this->api->handle(
$this->buildRequest('PATCH', '/users/1')
->withParsedBody([
'data' => [
'type' => 'users',
'id' => '1',
'attributes' => [
'writable' => 'value',
]
]
])
);
$this->assertTrue(empty($this->adapter->models['1']->writable));
}
public function test_attributes_can_run_callback_after_being_saved()
{
$called = false;
$this->api->resource('users', $this->adapter, function (Type $type) use (&$called) {
$type->updatable();
$type->attribute('writable')
->writable()
->saved(function ($model, $value, $request) use (&$called) {
$this->assertTrue($this->adapter->models['1']->saveWasCalled);
$this->assertSame($this->adapter->models['1'], $model);
$this->assertEquals('value', $value);
$this->assertInstanceOf(RequestInterface::class, $request);
$called = true;
});
});
$this->api->handle(
$this->buildRequest('PATCH', '/users/1')
->withParsedBody([
'data' => [
'type' => 'users',
'id' => '1',
'attributes' => [
'writable' => 'value',
]
]
])
);
$this->assertTrue($called);
}
public function test_attributes_can_have_default_values()
{
$this->api->resource('users', $this->adapter, function (Type $type) {
$type->creatable();
$type->attribute('name')
->default('Toby');
$type->attribute('color')
->default(function () {
return 'yellow';
});
});
$this->api->handle(
$this->buildRequest('POST', '/users')
->withParsedBody([
'data' => [
'type' => 'users',
]
])
);
$this->assertEquals('Toby', $this->adapter->createdModel->name);
$this->assertEquals('yellow', $this->adapter->createdModel->color);
}
public function test_attribute_default_callback_receives_correct_parameters()
{
$this->api->resource('users', $this->adapter, function (Type $type) {
$type->creatable();
$type->attribute('attribute')
->default(function ($request) {
$this->assertInstanceOf(RequestInterface::class, $request);
});
});
$this->api->handle(
$this->buildRequest('POST', '/users')
->withParsedBody([
'data' => [
'type' => 'users',
]
])
);
}
public function test_attribute_values_from_request_override_default_values()
{
$this->api->resource('users', $this->adapter, function (Type $type) {
$type->creatable();
$type->attribute('name')
->writable()
->default('Toby');
});
$this->api->handle(
$this->buildRequest('POST', '/users')
->withParsedBody([
'data' => [
'type' => 'users',
'attributes' => [
'name' => 'Franz',
]
]
])
);
$this->assertEquals('Franz', $this->adapter->createdModel->name);
}
public function test_attributes_can_be_validated()
{
$this->api->resource('users', $this->adapter, function (Type $type) {
$type->creatable();
$type->attribute('name')
->writable()
->validate(function ($fail, $value, $model, $request, $field) {
$this->assertEquals('Toby', $value);
$this->assertSame($this->adapter->createdModel, $model);
$this->assertInstanceOf(ServerRequestInterface::class, $request);
$this->assertInstanceOf(Attribute::class, $field);
$fail('detail');
});
});
$this->expectException(UnprocessableEntityException::class);
try {
$this->api->handle(
$this->buildRequest('POST', '/users')
->withParsedBody([
'data' => [
'type' => 'users',
'attributes' => [
'name' => 'Toby',
]
]
])
);
} catch (ErrorProviderInterface $e) {
$document = new ErrorDocument(...$e->getJsonApiErrors());
$this->assertArraySubset([
'errors' => [
[
'status' => '422',
'source' => [
'pointer' => '/data/attributes/name'
],
'detail' => 'detail'
]
]
], json_decode(json_encode($document), true));
throw $e;
}
}
}

View File

@ -1,174 +0,0 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\feature;
use Tobyz\JsonApiServer\JsonApi;
use Tobyz\JsonApiServer\Schema\Type;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
use Tobyz\Tests\JsonApiServer\MockAdapter;
class BasicTest extends AbstractTestCase
{
/**
* @var JsonApi
*/
private $api;
public function setUp(): void
{
$this->api = new JsonApi('http://example.com');
$adapter = new MockAdapter([
'1' => (object) [
'id' => '1',
'name' => 'Toby',
],
'2' => (object) [
'id' => '2',
'name' => 'Franz',
],
]);
$this->api->resource('users', $adapter, function (Type $type) {
$type->attribute('name')->writable();
$type->creatable();
$type->updatable();
$type->deletable();
});
}
public function test_show_resource()
{
$response = $this->api->handle(
$this->buildRequest('GET', '/users/1')
);
$this->assertEquals(200, $response->getStatusCode());
$this->assertJsonApiDocumentSubset([
'data' => [
'type' => 'users',
'id' => '1',
'attributes' => [
'name' => 'Toby'
],
'links' => [
'self' => 'http://example.com/users/1'
]
]
], $response->getBody());
}
public function test_list_resources()
{
$response = $this->api->handle(
$this->buildRequest('GET', '/users')
);
$this->assertEquals(200, $response->getStatusCode());
$this->assertJsonApiDocumentSubset([
'data' => [
[
'type' => 'users',
'id' => '1',
'attributes' => [
'name' => 'Toby'
],
'links' => [
'self' => 'http://example.com/users/1'
]
],
[
'type' => 'users',
'id' => '2',
'attributes' => [
'name' => 'Franz'
],
'links' => [
'self' => 'http://example.com/users/2'
]
]
]
], $response->getBody());
}
public function test_create_resource()
{
$response = $this->api->handle(
$this->buildRequest('POST', '/users')
->withParsedBody([
'data' => [
'type' => 'users',
'attributes' => [
'name' => 'Bob',
],
],
])
);
$this->assertEquals(201, $response->getStatusCode());
$this->assertJsonApiDocumentSubset([
'data' => [
'type' => 'users',
'id' => '1',
'attributes' => [
'name' => 'Bob',
],
'links' => [
'self' => 'http://example.com/users/1',
],
],
], $response->getBody());
}
public function test_update_resource()
{
$response = $this->api->handle(
$this->buildRequest('PATCH', '/users/1')
->withParsedBody([
'data' => [
'type' => 'users',
'id' => '1',
'attributes' => [
'name' => 'Bob',
],
],
])
);
$this->assertEquals(200, $response->getStatusCode());
$this->assertJsonApiDocumentSubset([
'data' => [
'type' => 'users',
'id' => '1',
'attributes' => [
'name' => 'Bob',
],
'links' => [
'self' => 'http://example.com/users/1',
],
],
], $response->getBody());
}
public function test_delete_resource()
{
$response = $this->api->handle(
$this->buildRequest('DELETE', '/users/1')
);
$this->assertEquals(204, $response->getStatusCode());
}
}

View File

@ -0,0 +1,51 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\feature;
use Tobyz\JsonApiServer\JsonApi;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
use Tobyz\Tests\JsonApiServer\MockAdapter;
class CountabilityTest extends AbstractTestCase
{
/**
* @var JsonApi
*/
private $api;
/**
* @var MockAdapter
*/
private $adapter;
public function setUp(): void
{
$this->api = new JsonApi('http://example.com');
$this->adapter = new MockAdapter();
}
public function test_total_number_of_resources_and_last_pagination_link_is_included_by_default()
{
$this->markTestIncomplete();
}
public function test_types_can_be_made_uncountable()
{
$this->markTestIncomplete();
}
public function test_types_can_be_made_countable()
{
$this->markTestIncomplete();
}
}

View File

@ -0,0 +1,79 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\feature;
use Tobyz\JsonApiServer\JsonApi;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
use Tobyz\Tests\JsonApiServer\MockAdapter;
class CreateTest extends AbstractTestCase
{
/**
* @var JsonApi
*/
private $api;
/**
* @var MockAdapter
*/
private $adapter;
public function setUp(): void
{
$this->api = new JsonApi('http://example.com');
$this->adapter = new MockAdapter();
}
public function test_resources_are_not_creatable_by_default()
{
$this->markTestIncomplete();
}
public function test_resource_creation_can_be_explicitly_enabled()
{
$this->markTestIncomplete();
}
public function test_resource_creation_can_be_conditionally_enabled()
{
$this->markTestIncomplete();
}
public function test_resource_creation_can_be_explicitly_disabled()
{
$this->markTestIncomplete();
}
public function test_resource_creation_can_be_conditionally_disabled()
{
$this->markTestIncomplete();
}
public function test_new_models_are_supplied_by_the_adapter()
{
$this->markTestIncomplete();
}
public function test_resources_can_provide_custom_models()
{
$this->markTestIncomplete();
}
public function test_creating_a_resource_calls_the_save_adapter_method()
{
$this->markTestIncomplete();
}
// saver...
// listeners...
}

View File

@ -0,0 +1,69 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\feature;
use Tobyz\JsonApiServer\JsonApi;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
use Tobyz\Tests\JsonApiServer\MockAdapter;
class DeleteTest extends AbstractTestCase
{
/**
* @var JsonApi
*/
private $api;
/**
* @var MockAdapter
*/
private $adapter;
public function setUp(): void
{
$this->api = new JsonApi('http://example.com');
$this->adapter = new MockAdapter();
}
public function test_resources_are_not_deletable_by_default()
{
$this->markTestIncomplete();
}
public function test_resource_deletion_can_be_explicitly_enabled()
{
$this->markTestIncomplete();
}
public function test_resource_deletion_can_be_conditionally_enabled()
{
$this->markTestIncomplete();
}
public function test_resource_deletion_can_be_explicitly_disabled()
{
$this->markTestIncomplete();
}
public function test_resource_deletion_can_be_conditionally_disabled()
{
$this->markTestIncomplete();
}
public function test_deleting_a_resource_calls_the_delete_adapter_method()
{
$this->markTestIncomplete();
}
// deleter...
// listeners...
}

View File

@ -0,0 +1,49 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\feature;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
class FieldDefaultValuesTest extends AbstractTestCase
{
public function setUp(): void
{
}
public function test_attributes_have_no_default_value_by_default()
{
$this->markTestIncomplete();
}
public function test_attributes_can_have_default_values()
{
$this->markTestIncomplete();
}
public function test_attributes_can_have_default_value_closures()
{
$this->markTestIncomplete();
}
public function test_attribute_default_value_callback_receives_correct_parameters()
{
$this->markTestIncomplete();
}
public function test_attribute_values_from_request_override_default_values()
{
$this->markTestIncomplete();
}
// to_one, to_many...
}

View File

@ -0,0 +1,59 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\feature;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
class FieldFiltersTest extends AbstractTestCase
{
public function setUp(): void
{
}
public function test_resources_can_be_filtered_by_id()
{
$this->markTestIncomplete();
}
public function test_attributes_are_not_filterable_by_default()
{
$this->markTestIncomplete();
}
public function test_attributes_can_be_explicitly_not_filterable()
{
$this->markTestIncomplete();
}
public function test_attributes_can_be_filterable_by_their_value()
{
$this->markTestIncomplete();
}
public function test_attributes_can_be_filterable_with_custom_logic()
{
$this->markTestIncomplete();
}
public function test_attributes_filterable_callback_receives_correct_parameters()
{
$this->markTestIncomplete();
}
// to_one, to_many...
public function test_types_can_have_custom_filters()
{
$this->markTestIncomplete();
}
}

View File

@ -0,0 +1,34 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\feature;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
class FieldGettersTest extends AbstractTestCase
{
public function setUp(): void
{
}
public function test_attribute_values_are_retrieved_via_the_adapter_by_default()
{
$this->markTestIncomplete();
}
public function test_attribute_getters_allow_a_custom_value_to_be_used()
{
$this->markTestIncomplete();
}
// to_one, to_many...
}

View File

@ -0,0 +1,29 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\feature;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
class FieldListenersTest extends AbstractTestCase
{
public function setUp(): void
{
}
public function test_attributes_can_run_callback_after_being_saved()
{
$this->markTestIncomplete();
}
// to_one, to_many...
}

View File

@ -0,0 +1,34 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\feature;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
class FieldSaversTest extends AbstractTestCase
{
public function setUp(): void
{
}
public function test_attribute_savers_allow_custom_save_logic_to_be_performed_after_the_model_is_saved()
{
$this->markTestIncomplete();
}
public function test_attribute_savers_prevent_the_default_adapter_setter()
{
$this->markTestIncomplete();
}
// to_one, to_many...
}

View File

@ -0,0 +1,39 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\feature;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
class FieldSettersTest extends AbstractTestCase
{
public function setUp(): void
{
}
public function test_attributes_are_set_via_the_adapter_by_default()
{
$this->markTestIncomplete();
}
public function test_attribute_setters_allow_the_model_to_be_modified_before_it_is_saved()
{
$this->markTestIncomplete();
}
public function test_attribute_setters_prevent_the_default_adapter_setter()
{
$this->markTestIncomplete();
}
// to_one, to_many...
}

View File

@ -0,0 +1,39 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\feature;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
class FieldValidationTest extends AbstractTestCase
{
public function setUp(): void
{
}
public function test_attributes_can_define_multiple_validators()
{
$this->markTestIncomplete();
}
public function test_attribute_validators_receive_correct_parameters()
{
$this->markTestIncomplete();
}
public function test_attribute_validation_errors_contain_correct_information()
{
$this->markTestIncomplete();
}
// to_one, to_many...
}

View File

@ -12,6 +12,7 @@
namespace Tobyz\Tests\JsonApiServer\feature;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Tobyz\JsonApiServer\JsonApi;
use Tobyz\JsonApiServer\Schema\Type;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
@ -38,12 +39,10 @@ class FieldVisibilityTest extends AbstractTestCase
]);
}
public function test_fields_are_visible_by_default()
public function test_attributes_are_visible_by_default()
{
$this->api->resource('users', new MockAdapter, function (Type $type) {
$type->attribute('visibleAttribute');
$type->hasOne('visibleHasOne');
$type->hasMany('visibleHasMany');
$type->attribute('visible');
});
$response = $this->api->handle(
@ -52,15 +51,14 @@ class FieldVisibilityTest extends AbstractTestCase
$document = json_decode($response->getBody(), true);
$attributes = $document['data']['attributes'] ?? [];
$relationships = $document['data']['relationships'] ?? [];
$this->assertArrayHasKey('visibleAttribute', $attributes);
$this->assertArrayHasKey('visibleHasOne', $relationships);
$this->assertArrayHasKey('visibleHasMany', $relationships);
$this->assertArrayHasKey('visible', $attributes);
}
public function test_fields_can_be_explicitly_visible()
public function test_attributes_can_be_explicitly_visible()
{
$this->markTestIncomplete();
$this->api->resource('users', new MockAdapter, function (Type $type) {
$type->attribute('visibleAttribute')->visible();
$type->hasOne('visibleHasOne')->visible();
@ -80,8 +78,10 @@ class FieldVisibilityTest extends AbstractTestCase
$this->assertArrayHasKey('visibleHasMany', $relationships);
}
public function test_fields_can_be_conditionally_visible()
public function test_attributes_can_be_conditionally_visible()
{
$this->markTestIncomplete();
$this->api->resource('users', new MockAdapter, function (Type $type) {
$type->attribute('visibleAttribute')
->visible(function () { return true; });
@ -119,8 +119,10 @@ class FieldVisibilityTest extends AbstractTestCase
$this->assertArrayNotHasKey('hiddenHasMany', $relationships);
}
public function test_visible_callback_receives_correct_parameters()
public function test_attribute_visible_callback_receives_correct_parameters()
{
$this->markTestIncomplete();
$called = 0;
$this->api->resource('users', $this->adapter, function (Type $type) use (&$called) {
@ -147,8 +149,10 @@ class FieldVisibilityTest extends AbstractTestCase
$this->assertEquals(3, $called);
}
public function test_fields_can_be_explicitly_hidden()
public function test_attributes_can_be_explicitly_hidden()
{
$this->markTestIncomplete();
$this->api->resource('users', new MockAdapter, function (Type $type) {
$type->attribute('hiddenAttribute')->hidden();
$type->hasOne('hiddenHasOne')->hidden();
@ -168,8 +172,10 @@ class FieldVisibilityTest extends AbstractTestCase
$this->assertArrayNotHasKey('hiddenHasMany', $relationships);
}
public function test_fields_can_be_conditionally_hidden()
public function test_attributes_can_be_conditionally_hidden()
{
$this->markTestIncomplete();
$this->api->resource('users', new MockAdapter, function (Type $type) {
$type->attribute('visibleAttribute')
->hidden(function () { return false; });
@ -207,8 +213,10 @@ class FieldVisibilityTest extends AbstractTestCase
$this->assertArrayNotHasKey('hiddenHasMany', $relationships);
}
public function test_hidden_callback_receives_correct_parameters()
public function test_attribute_hidden_callback_receives_correct_parameters()
{
$this->markTestIncomplete();
$called = 0;
$this->api->resource('users', $this->adapter, function (Type $type) use (&$called) {
@ -234,4 +242,6 @@ class FieldVisibilityTest extends AbstractTestCase
$this->assertEquals(3, $called);
}
// to_one, to_many...
}

View File

@ -19,7 +19,7 @@ use Tobyz\JsonApiServer\Schema\Type;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
use Tobyz\Tests\JsonApiServer\MockAdapter;
class AttributeWritableTest extends AbstractTestCase
class FieldWritabilityTest extends AbstractTestCase
{
/**
* @var JsonApi
@ -112,30 +112,6 @@ class AttributeWritableTest extends AbstractTestCase
$this->assertEquals('value', $this->adapter->models['1']->writable);
}
public function test_attributes_can_be_conditionally_not_writable()
{
$this->api->resource('users', $this->adapter, function (Type $type) {
$type->updatable();
$type->attribute('writable')
->writable(function () { return false; });
});
$this->expectException(BadRequestException::class);
$this->api->handle(
$this->buildRequest('PATCH', '/users/1')
->withParsedBody([
'data' => [
'type' => 'users',
'id' => '1',
'attributes' => [
'writable' => 'value',
]
]
])
);
}
public function test_attribute_writable_callback_receives_correct_parameters()
{
$called = false;
@ -247,28 +223,5 @@ class AttributeWritableTest extends AbstractTestCase
$this->assertTrue($called);
}
public function test_attributes_can_be_conditionally_not_readonly()
{
$this->api->resource('users', $this->adapter, function (Type $type) {
$type->updatable();
$type->attribute('writable')
->readonly(function () { return false; });
});
$response = $this->api->handle(
$this->buildRequest('PATCH', '/users/1')
->withParsedBody([
'data' => [
'type' => 'users',
'id' => '1',
'attributes' => [
'writable' => 'value',
]
]
])
);
$this->assertEquals(200, $response->getStatusCode());
$this->assertEquals('value', $this->adapter->models['1']->writable);
}
// to_one, to_many...
}

View File

@ -0,0 +1,46 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\feature;
use Tobyz\JsonApiServer\JsonApi;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
use Tobyz\Tests\JsonApiServer\MockAdapter;
class MetaTest extends AbstractTestCase
{
/**
* @var JsonApi
*/
private $api;
/**
* @var MockAdapter
*/
private $adapter;
public function setUp(): void
{
$this->api = new JsonApi('http://example.com');
$this->adapter = new MockAdapter();
}
public function test_meta_fields_can_be_added_to_the_document_with_a_value()
{
$this->markTestIncomplete();
}
public function test_meta_fields_can_be_added_to_the_document_with_a_closure()
{
$this->markTestIncomplete();
}
}

View File

@ -0,0 +1,66 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\feature;
use Tobyz\JsonApiServer\JsonApi;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
use Tobyz\Tests\JsonApiServer\MockAdapter;
class PaginationTest extends AbstractTestCase
{
/**
* @var JsonApi
*/
private $api;
/**
* @var MockAdapter
*/
private $adapter;
public function setUp(): void
{
$this->api = new JsonApi('http://example.com');
$this->adapter = new MockAdapter();
}
public function test_resource_collections_are_paginated_to_20_records_by_default()
{
$this->markTestIncomplete();
}
public function test_types_can_specify_the_default_number_of_resources_per_page()
{
$this->markTestIncomplete();
}
public function test_types_can_disable_pagination_by_default()
{
$this->markTestIncomplete();
}
public function test_the_maximum_limit_is_50_by_default()
{
$this->markTestIncomplete();
}
public function test_types_can_specify_the_maximum_limit()
{
$this->markTestIncomplete();
}
public function test_types_can_remove_the_maximum_limit()
{
$this->markTestIncomplete();
}
}

View File

@ -0,0 +1,84 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\feature;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
class RelationshipInclusionTest extends AbstractTestCase
{
public function setUp(): void
{
}
public function test_to_one_relationships_are_not_includable_by_default()
{
$this->markTestIncomplete();
}
public function test_to_one_relationships_can_be_made_includable()
{
$this->markTestIncomplete();
}
public function test_to_one_relationships_can_be_made_not_includable()
{
$this->markTestIncomplete();
}
public function test_included_to_one_relationships_are_preloaded_via_the_adapter()
{
$this->markTestIncomplete();
}
public function test_to_one_relationships_can_have_custom_preloaders()
{
$this->markTestIncomplete();
}
// to_many...
public function test_multiple_relationships_can_be_included()
{
$this->markTestIncomplete();
}
public function test_nested_relationships_can_be_included()
{
$this->markTestIncomplete();
}
public function test_nested_relationships_include_intermediate_resources()
{
$this->markTestIncomplete();
}
public function test_relationships_can_be_included_on_single_resource_requests()
{
$this->markTestIncomplete();
}
public function test_relationships_can_be_included_on_resource_listing_requests()
{
$this->markTestIncomplete();
}
public function test_relationships_can_be_included_on_create_requests()
{
$this->markTestIncomplete();
}
public function test_relationships_can_be_included_on_update_requests()
{
$this->markTestIncomplete();
}
}

View File

@ -0,0 +1,39 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\feature;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
class RelationshipLinkageTest extends AbstractTestCase
{
public function setUp(): void
{
}
public function test_to_one_relationships_do_not_show_linkage_by_default()
{
$this->markTestIncomplete();
}
public function test_to_one_relationship_linkage_can_be_enabled()
{
$this->markTestIncomplete();
}
public function test_to_one_relationships_linkage_can_be_re_disabled()
{
$this->markTestIncomplete();
}
// to_many...
}

View File

@ -0,0 +1,39 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\feature;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
class RelationshipLinksTest extends AbstractTestCase
{
public function setUp(): void
{
}
public function test_to_one_relationships_have_self_and_related_links_by_default()
{
$this->markTestIncomplete();
}
public function test_to_one_relationship_links_can_be_disabled()
{
$this->markTestIncomplete();
}
public function test_to_one_relationships_links_can_be_re_enabled()
{
$this->markTestIncomplete();
}
// to_many...
}

View File

@ -0,0 +1,46 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\feature;
use Tobyz\JsonApiServer\JsonApi;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
use Tobyz\Tests\JsonApiServer\MockAdapter;
class RelationshipMetaTest extends AbstractTestCase
{
/**
* @var JsonApi
*/
private $api;
/**
* @var MockAdapter
*/
private $adapter;
public function setUp(): void
{
$this->api = new JsonApi('http://example.com');
$this->adapter = new MockAdapter();
}
public function test_meta_fields_can_be_added_to_a_relationship_with_a_value()
{
$this->markTestIncomplete();
}
public function test_meta_fields_can_be_added_to_a_relationship_with_a_closure()
{
$this->markTestIncomplete();
}
}

View File

@ -0,0 +1,44 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\feature;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
class RelationshipTypesTest extends AbstractTestCase
{
public function setUp(): void
{
}
public function test_to_one_relationship_type_is_inferred_from_relationship_name()
{
$this->markTestIncomplete();
}
public function test_to_one_relationships_can_specify_a_type()
{
$this->markTestIncomplete();
}
public function test_to_one_relationships_can_be_polymorphic()
{
$this->markTestIncomplete();
}
public function test_nested_includes_cannot_be_requested_on_polymorphic_to_one_relationships()
{
$this->markTestIncomplete();
}
// to_many...
}

View File

@ -0,0 +1,59 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\feature;
use Psr\Http\Message\ServerRequestInterface;
use Tobyz\JsonApiServer\Exception\BadRequestException;
use Tobyz\JsonApiServer\JsonApi;
use Tobyz\JsonApiServer\Schema\Type;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
use Tobyz\Tests\JsonApiServer\MockAdapter;
class ScopesTest extends AbstractTestCase
{
/**
* @var JsonApi
*/
private $api;
/**
* @var MockAdapter
*/
private $adapter;
public function setUp(): void
{
$this->api = new JsonApi('http://example.com');
$this->adapter = new MockAdapter();
}
public function test_scopes_are_applied_to_the_resource_listing_query()
{
$this->markTestIncomplete();
}
public function test_scopes_are_applied_to_the_show_resource_query()
{
$this->markTestIncomplete();
}
public function test_scopes_are_applied_to_the_update_resource_query()
{
$this->markTestIncomplete();
}
public function test_scopes_are_applied_to_the_delete_resource_query()
{
$this->markTestIncomplete();
}
}

View File

@ -18,7 +18,7 @@ use Tobyz\JsonApiServer\Schema\Type;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
use Tobyz\Tests\JsonApiServer\MockAdapter;
class AttributeSortableTest extends AbstractTestCase
class SortingTest extends AbstractTestCase
{
/**
* @var JsonApi
@ -37,7 +37,21 @@ class AttributeSortableTest extends AbstractTestCase
$this->adapter = new MockAdapter();
}
public function test_attributes_can_be_sortable()
public function test_attributes_are_not_sortable_by_default()
{
$this->api->resource('users', $this->adapter, function (Type $type) {
$type->attribute('name');
});
$this->expectException(BadRequestException::class);
$this->api->handle(
$this->buildRequest('GET', '/users')
->withQueryParams(['sort' => 'name'])
);
}
public function test_attributes_can_be_sortable_by_their_value()
{
$attribute = null;
@ -77,18 +91,9 @@ class AttributeSortableTest extends AbstractTestCase
$this->assertTrue(empty($this->adapter->query->sort));
}
public function test_attributes_are_not_sortable_by_default()
public function test_attribute_sortable_callback_receives_correct_parameters()
{
$this->api->resource('users', $this->adapter, function (Type $type) {
$type->attribute('name');
});
$this->expectException(BadRequestException::class);
$this->api->handle(
$this->buildRequest('GET', '/users')
->withQueryParams(['sort' => 'name'])
);
$this->markTestIncomplete();
}
public function test_attributes_can_be_explicitly_not_sortable()
@ -104,4 +109,24 @@ class AttributeSortableTest extends AbstractTestCase
->withQueryParams(['sort' => 'name'])
);
}
public function test_types_can_have_custom_sort_fields()
{
$this->markTestIncomplete();
}
public function test_types_can_have_a_default_sort()
{
$this->markTestIncomplete();
}
public function test_multiple_sort_fields_can_be_requested()
{
$this->markTestIncomplete();
}
public function test_sort_fields_can_be_descending_with_minus_prefix()
{
$this->markTestIncomplete();
}
}

View File

@ -0,0 +1,69 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\feature;
use Tobyz\JsonApiServer\JsonApi;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
use Tobyz\Tests\JsonApiServer\MockAdapter;
class UpdateTest extends AbstractTestCase
{
/**
* @var JsonApi
*/
private $api;
/**
* @var MockAdapter
*/
private $adapter;
public function setUp(): void
{
$this->api = new JsonApi('http://example.com');
$this->adapter = new MockAdapter();
}
public function test_resources_are_not_updatable_by_default()
{
$this->markTestIncomplete();
}
public function test_resource_updating_can_be_explicitly_enabled()
{
$this->markTestIncomplete();
}
public function test_resource_updating_can_be_conditionally_enabled()
{
$this->markTestIncomplete();
}
public function test_resource_updating_can_be_explicitly_disabled()
{
$this->markTestIncomplete();
}
public function test_resource_updating_can_be_conditionally_disabled()
{
$this->markTestIncomplete();
}
public function test_updating_a_resource_calls_the_save_adapter_method()
{
$this->markTestIncomplete();
}
// saver...
// listeners...
}

View File

@ -18,6 +18,9 @@ use Tobyz\JsonApiServer\Schema\Type;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
use Tobyz\Tests\JsonApiServer\MockAdapter;
/**
* @see https://jsonapi.org/format/#content-negotiation
*/
class ContentNegotiationTest extends AbstractTestCase
{
/**
@ -33,7 +36,7 @@ class ContentNegotiationTest extends AbstractTestCase
});
}
public function testJsonApiContentTypeIsReturned()
public function test_json_api_content_type_is_returned()
{
$response = $this->api->handle(
$this->buildRequest('GET', '/users/1')
@ -45,7 +48,7 @@ class ContentNegotiationTest extends AbstractTestCase
);
}
public function testErrorWhenValidRequestContentTypeHasParameters()
public function test_error_when_valid_request_content_type_has_parameters()
{
$request = $this->buildRequest('PATCH', '/users/1')
->withHeader('Content-Type', 'application/vnd.api+json;profile="http://example.com/last-modified"');
@ -55,7 +58,7 @@ class ContentNegotiationTest extends AbstractTestCase
$this->api->handle($request);
}
public function testErrorWhenAllValidAcceptsHaveParameters()
public function test_error_when_all_valid_accepts_have_parameters()
{
$request = $this->buildRequest('GET', '/users/1')
->withHeader('Accept', 'application/vnd.api+json;profile="http://example.com/last-modified", application/vnd.api+json;profile="http://example.com/versioning"');
@ -65,7 +68,7 @@ class ContentNegotiationTest extends AbstractTestCase
$this->api->handle($request);
}
public function testSuccessWhenOnlySomeAcceptsHaveParameters()
public function test_success_when_only_some_accepts_have_parameters()
{
$response = $this->api->handle(
$this->buildRequest('GET', '/users/1')

View File

@ -0,0 +1,79 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\specification;
use Tobyz\JsonApiServer\JsonApi;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
use Tobyz\Tests\JsonApiServer\MockAdapter;
/**
* @see https://jsonapi.org/format/1.0/#crud-creating
*/
class CreatingResourcesTest extends AbstractTestCase
{
/**
* @var JsonApi
*/
private $api;
/**
* @var MockAdapter
*/
private $adapter;
public function setUp(): void
{
$this->api = new JsonApi('http://example.com');
$this->adapter = new MockAdapter();
}
public function test_bad_request_error_if_body_does_not_contain_data_type()
{
$this->markTestIncomplete();
}
public function test_bad_request_error_if_relationship_does_not_contain_data()
{
$this->markTestIncomplete();
}
public function test_forbidden_error_if_client_generated_id_provided()
{
$this->markTestIncomplete();
}
public function test_created_response_if_resource_successfully_created()
{
$this->markTestIncomplete();
}
public function test_created_response_includes_created_data()
{
$this->markTestIncomplete();
}
public function test_created_response_includes_location_header_and_matches_self_link()
{
$this->markTestIncomplete();
}
public function test_not_found_error_if_references_resource_that_does_not_exist()
{
$this->markTestIncomplete();
}
public function test_conflict_error_if_type_does_not_match_endpoint()
{
$this->markTestIncomplete();
}
}

View File

@ -0,0 +1,49 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\specification;
use Tobyz\JsonApiServer\JsonApi;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
use Tobyz\Tests\JsonApiServer\MockAdapter;
/**
* @see https://jsonapi.org/format/1.0/#crud-deleting
*/
class DeletingResourcesTest extends AbstractTestCase
{
/**
* @var JsonApi
*/
private $api;
/**
* @var MockAdapter
*/
private $adapter;
public function setUp(): void
{
$this->api = new JsonApi('http://example.com');
$this->adapter = new MockAdapter();
}
public function test_no_content_response_if_resource_successfully_deleted()
{
$this->markTestIncomplete();
}
public function test_not_found_error_if_resource_does_not_exist()
{
$this->markTestIncomplete();
}
}

View File

@ -0,0 +1,74 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\specification;
use Tobyz\JsonApiServer\JsonApi;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
use Tobyz\Tests\JsonApiServer\MockAdapter;
/**
* @see https://jsonapi.org/format/#fetching-resources
*/
class FetchingResourcesTest extends AbstractTestCase
{
/**
* @var JsonApi
*/
private $api;
/**
* @var MockAdapter
*/
private $adapter;
public function setUp(): void
{
$this->api = new JsonApi('http://example.com');
$this->adapter = new MockAdapter();
}
public function test_data_for_resource_collection_is_array_of_resource_objects()
{
$this->markTestIncomplete();
}
public function test_data_for_empty_resource_collection_is_empty_array()
{
$this->markTestIncomplete();
}
public function test_data_for_individual_resource_is_resource_object()
{
$this->markTestIncomplete();
}
public function test_not_found_error_if_resource_type_does_not_exist()
{
$this->markTestIncomplete();
}
public function test_not_found_error_if_resource_does_not_exist()
{
$this->markTestIncomplete();
}
public function test_resource_collection_document_contains_self_link()
{
$this->markTestIncomplete();
}
public function test_resource_document_contains_self_link()
{
$this->markTestIncomplete();
}
}

View File

@ -0,0 +1,44 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\specification;
use Tobyz\JsonApiServer\JsonApi;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
use Tobyz\Tests\JsonApiServer\MockAdapter;
/**
* @see https://jsonapi.org/format/#document-jsonapi-object
*/
class JsonApiTest extends AbstractTestCase
{
/**
* @var JsonApi
*/
private $api;
/**
* @var MockAdapter
*/
private $adapter;
public function setUp(): void
{
$this->api = new JsonApi('http://example.com');
$this->adapter = new MockAdapter();
}
public function test_document_includes_jsonapi_member_with_version_1_0()
{
$this->markTestIncomplete();
}
}

View File

@ -0,0 +1,85 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\specification;
use Tobyz\JsonApiServer\JsonApi;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
use Tobyz\Tests\JsonApiServer\MockAdapter;
/**
* @see https://jsonapi.org/format/1.0/#fetching-pagination
* @todo Create a profile for offset pagination strategy
*/
class OffsetPaginationTest extends AbstractTestCase
{
/**
* @var JsonApi
*/
private $api;
/**
* @var MockAdapter
*/
private $adapter;
public function setUp(): void
{
$this->api = new JsonApi('http://example.com');
$this->adapter = new MockAdapter();
}
public function test_can_request_limit_on_resource_collection()
{
$this->markTestIncomplete();
}
public function test_can_request_offset_on_resource_collection()
{
$this->markTestIncomplete();
}
public function test_first_pagination_link_is_correct()
{
$this->markTestIncomplete();
}
public function test_last_pagination_link_is_correct()
{
$this->markTestIncomplete();
}
public function test_next_pagination_link_is_correct()
{
$this->markTestIncomplete();
}
public function test_next_pagination_link_is_not_included_on_last_page()
{
$this->markTestIncomplete();
}
public function test_prev_pagination_link_is_correct()
{
$this->markTestIncomplete();
}
public function test_prev_pagination_link_is_not_included_on_last_page()
{
$this->markTestIncomplete();
}
public function test_pagination_links_retain_other_query_parameters()
{
$this->markTestIncomplete();
}
}

View File

@ -0,0 +1,44 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\specification;
use Tobyz\JsonApiServer\JsonApi;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
use Tobyz\Tests\JsonApiServer\MockAdapter;
/**
* @see https://jsonapi.org/format/#query-parameters
*/
class QueryParametersTest extends AbstractTestCase
{
/**
* @var JsonApi
*/
private $api;
/**
* @var MockAdapter
*/
private $adapter;
public function setUp(): void
{
$this->api = new JsonApi('http://example.com');
$this->adapter = new MockAdapter();
}
public function test_bad_request_error_if_unknown_query_parameters()
{
$this->markTestIncomplete();
}
}

View File

@ -0,0 +1,64 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\specification;
use Tobyz\JsonApiServer\JsonApi;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
use Tobyz\Tests\JsonApiServer\MockAdapter;
/**
* @see https://jsonapi.org/format/1.0/#fetching-sparse-fieldsets
*/
class SparseFieldsetsTest extends AbstractTestCase
{
/**
* @var JsonApi
*/
private $api;
/**
* @var MockAdapter
*/
private $adapter;
public function setUp(): void
{
$this->api = new JsonApi('http://example.com');
$this->adapter = new MockAdapter();
}
public function test_can_request_sparse_fieldsets_for_a_type()
{
$this->markTestIncomplete();
}
public function test_can_request_sparse_fieldsets_for_multiple_types()
{
$this->markTestIncomplete();
}
public function test_can_request_sparse_fieldsets_on_resource_collections()
{
$this->markTestIncomplete();
}
public function test_can_request_sparse_fieldsets_on_create()
{
$this->markTestIncomplete();
}
public function test_can_request_sparse_fieldsets_on_update()
{
$this->markTestIncomplete();
}
}

View File

@ -0,0 +1,84 @@
<?php
/*
* This file is part of tobyz/json-api-server.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\specification;
use Tobyz\JsonApiServer\JsonApi;
use Tobyz\Tests\JsonApiServer\AbstractTestCase;
use Tobyz\Tests\JsonApiServer\MockAdapter;
/**
* @see https://jsonapi.org/format/1.0/#crud-updating
*/
class UpdatingResourcesTest extends AbstractTestCase
{
/**
* @var JsonApi
*/
private $api;
/**
* @var MockAdapter
*/
private $adapter;
public function setUp(): void
{
$this->api = new JsonApi('http://example.com');
$this->adapter = new MockAdapter();
}
public function test_bad_request_error_if_body_does_not_contain_data_type_and_id()
{
$this->markTestIncomplete();
}
public function test_only_included_attributes_are_processed()
{
$this->markTestIncomplete();
}
public function test_only_included_relationships_are_processed()
{
$this->markTestIncomplete();
}
public function test_bad_request_error_if_relationship_does_not_contain_data()
{
$this->markTestIncomplete();
}
public function test_ok_response_if_resource_successfully_updated()
{
$this->markTestIncomplete();
}
public function test_ok_response_includes_updated_data()
{
$this->markTestIncomplete();
}
public function test_not_found_error_if_resource_does_not_exist()
{
$this->markTestIncomplete();
}
public function test_not_found_error_if_references_resource_that_does_not_exist()
{
$this->markTestIncomplete();
}
public function test_conflict_error_if_type_and_id_does_not_match_endpoint()
{
$this->markTestIncomplete();
}
}

View File

@ -16,7 +16,7 @@ use Tobyz\JsonApiServer\Http\MediaTypes;
class MediaTypesTest extends TestCase
{
public function testContainsOnExactMatch()
public function test_contains_on_exact_match()
{
$header = new MediaTypes('application/json');
@ -25,7 +25,7 @@ class MediaTypesTest extends TestCase
);
}
public function testContainsDoesNotMatchWithExtraParameters()
public function test_contains_does_not_match_with_extra_parameters()
{
$header = new MediaTypes('application/json; profile=foo');
@ -34,7 +34,7 @@ class MediaTypesTest extends TestCase
);
}
public function testContainsMatchesWhenOnlyWeightIsProvided()
public function test_contains_matches_when_only_weight_is_provided()
{
$header = new MediaTypes('application/json; q=0.8');
@ -43,7 +43,7 @@ class MediaTypesTest extends TestCase
);
}
public function testContainsDoesNotMatchWithExtraParametersBeforeWeight()
public function test_contains_does_not_match_with_extra_parameters_before_weight()
{
$header = new MediaTypes('application/json; profile=foo; q=0.8');
@ -52,7 +52,7 @@ class MediaTypesTest extends TestCase
);
}
public function testContainsMatchesWithExtraParametersAfterWeight()
public function test_contains_matches_with_extra_parameters_after_weight()
{
$header = new MediaTypes('application/json; q=0.8; profile=foo');
@ -61,7 +61,7 @@ class MediaTypesTest extends TestCase
);
}
public function testContainsMatchesWhenOneOfMultipleMediaTypesIsValid()
public function test_contains_matches_when_one_of_multiple_media_types_is_valid()
{
$header = new MediaTypes('application/json; profile=foo, application/json; q=0.6');

View File

@ -0,0 +1,27 @@
<?php
/*
* This file is part of JSON-API.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\unit\Http;
use PHPUnit\Framework\TestCase;
class JsonApiTest extends TestCase
{
public function test_error_converts_error_provider_to_json_api_response()
{
$this->markTestIncomplete();
}
public function test_error_converts_non_error_provider_to_internal_server_error()
{
$this->markTestIncomplete();
}
}

View File

@ -0,0 +1,43 @@
<?php
/*
* This file is part of JSON-API.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tobyz\Tests\JsonApiServer\unit\Schema;
use PHPUnit\Framework\TestCase;
use Tobyz\JsonApiServer\Schema\Type;
class TypeTest extends TestCase
{
public function test_returns_an_existing_field_with_the_same_name_of_the_same_type()
{
$type = new Type;
$attribute = $type->attribute('dogs');
$attributeAgain = $type->attribute('dogs');
$fields = $type->getFields();
$this->assertSame($attribute, $attributeAgain);
$this->assertEquals(1, count($fields));
}
public function test_overwrites_an_existing_field_with_the_same_name_of_a_different_type()
{
$type = new Type;
$attribute = $type->attribute('dogs');
$hasOne = $type->hasOne('dogs');
$fields = $type->getFields();
$this->assertNotSame($attribute, $hasOne);
$this->assertEquals(1, count($fields));
$this->assertSame($hasOne, $fields['dogs']);
}
}