Skip to content

Commit

Permalink
Merge 2712502 into cd198d2
Browse files Browse the repository at this point in the history
  • Loading branch information
soyuka committed May 22, 2021
2 parents cd198d2 + 2712502 commit dd4b162
Show file tree
Hide file tree
Showing 89 changed files with 3,469 additions and 92 deletions.
41 changes: 27 additions & 14 deletions .github/workflows/ci.yml
Expand Up @@ -10,12 +10,13 @@ env:

jobs:
php-cs-fixer:
name: PHP-cs-fixer (PHP ${{ matrix.php }})
runs-on: ubuntu-latest
timeout-minutes: 20
strategy:
matrix:
php:
- '7.4'
- '8'
fail-fast: false
env:
PHP_CS_FIXER_FUTURE_MODE: '1'
Expand All @@ -34,16 +35,17 @@ jobs:
run: php-cs-fixer fix --dry-run --diff --ansi

phpstan:
name: PHPStan
name: PHPStan (PHP ${{ matrix.php }})
runs-on: ubuntu-latest
timeout-minutes: 20
strategy:
matrix:
php:
- '7.4'
- '8'
fail-fast: false
env:
APP_DEBUG: '1' # https://github.com/phpstan/phpstan-symfony/issues/37
SYMFONY_PHPUNIT_VERSION: '9.5'
steps:
- name: Checkout
uses: actions/checkout@v2
Expand All @@ -69,8 +71,6 @@ jobs:
- name: Require Symfony Uid
run: composer require symfony/uid --dev --no-interaction --no-progress --ansi
- name: Install PHPUnit
env:
SYMFONY_PHPUNIT_VERSION: '9.5'
run: vendor/bin/simple-phpunit --version
- name: Cache PHPStan results
uses: actions/cache@v2
Expand All @@ -85,8 +85,6 @@ jobs:
run: |
tests/Fixtures/app/console cache:clear --ansi
- name: Run PHPStan analysis
env:
SYMFONY_PHPUNIT_VERSION: '9.5'
run: ./vendor/bin/phpstan analyse --no-interaction --no-progress --no-interaction --ansi

phpunit:
Expand Down Expand Up @@ -247,17 +245,27 @@ jobs:
if: (startsWith(matrix.php, '8.0'))
run: rm -Rf tests/Fixtures/app/var/cache/*
- name: Run Behat tests
if: (!startsWith(matrix.php, '8.0'))
run: |
mkdir -p build/logs/behat
if [ "$COVERAGE" = '1' ]; then
vendor/bin/behat --out=std --format=progress --format=junit --out=build/logs/behat/junit --profile=default-coverage --no-interaction
vendor/bin/behat --out=std --format=progress --format=junit --out=build/logs/behat/junit --profile=default-coverage --no-interaction --tags='~@php8'
else
if [ "${{ matrix.php }}" = '7.1' ]; then
vendor/bin/behat --out=std --format=progress --format=junit --out=build/logs/behat/junit --profile=default --no-interaction --tags='~@symfony/uid'
vendor/bin/behat --out=std --format=progress --format=junit --out=build/logs/behat/junit --profile=default --no-interaction --tags='~@symfony/uid&&~@php8'
else
vendor/bin/behat --out=std --format=progress --format=junit --out=build/logs/behat/junit --profile=default --no-interaction
vendor/bin/behat --out=std --format=progress --format=junit --out=build/logs/behat/junit --profile=default --no-interaction --tags='~@php8'
fi
fi
- name: Run Behat tests
if: (startsWith(matrix.php, '8.0'))
run: |
mkdir -p build/logs/behat
if [ "$COVERAGE" = '1' ]; then
vendor/bin/behat --out=std --format=progress --format=junit --out=build/logs/behat/junit --profile=default-coverage --no-interaction
else
vendor/bin/behat --out=std --format=progress --format=junit --out=build/logs/behat/junit --profile=default --no-interaction
fi
- name: Merge code coverage reports
if: matrix.coverage
run: |
Expand Down Expand Up @@ -389,7 +397,7 @@ jobs:
run: tests/Fixtures/app/console cache:clear --ansi
- name: Run Behat tests
# @TODO remove the tag "@symfony/uid" in 3.0
run: vendor/bin/behat --out=std --format=progress --profile=default --no-interaction --tags='~@symfony/uid'
run: vendor/bin/behat --out=std --format=progress --profile=default --no-interaction --tags='~@symfony/uid&&~php8'

postgresql:
name: Behat (PHP ${{ matrix.php }}) (PostgreSQL)
Expand Down Expand Up @@ -440,7 +448,7 @@ jobs:
run: tests/Fixtures/app/console cache:clear --ansi
- name: Run Behat tests
run: |
vendor/bin/behat --out=std --format=progress --profile=postgres --no-interaction -vv
vendor/bin/behat --out=std --format=progress --profile=postgres --no-interaction -vv --tags='~php8'
mysql:
name: Behat (PHP ${{ matrix.php }}) (MySQL)
Expand Down Expand Up @@ -500,7 +508,7 @@ jobs:
strategy:
matrix:
php:
- '7.4'
- '8'
fail-fast: false
env:
APP_ENV: mongodb
Expand Down Expand Up @@ -856,5 +864,10 @@ jobs:
- name: Clear test app cache
run: tests/Fixtures/app/console cache:clear --ansi
- name: Run Behat tests
run: vendor/bin/behat --out=std --format=progress --profile=default --no-interaction
run: |
if ( "${{ matrix.php }}" -eq '7.4' ) {
vendor/bin/behat --out=std --format=progress --profile=default --no-interaction --tags='~@php8'
} else {
vendor/bin/behat --out=std --format=progress --profile=default --no-interaction
}
3 changes: 2 additions & 1 deletion composer.json
Expand Up @@ -108,7 +108,8 @@
},
"autoload": {
"psr-4": {
"ApiPlatform\\Core\\": "src/"
"ApiPlatform\\Core\\": "src/",
"ApiPlatform\\": "src/Core"
}
},
"autoload-dev": {
Expand Down
11 changes: 6 additions & 5 deletions docs/adr/0002-resource-definition.md
Expand Up @@ -24,8 +24,7 @@ In API Platform, this resource identifier is also named [IRI (Internationalized
```php
<?php

#[Get]
#[Post]
#[Resource]
class Users
{
#[ApiProperty(iri="hydra:member")]
Expand All @@ -34,9 +33,11 @@ class Users
public float $averageRate;
}

#[Get]
#[Put]
#[Delete]
#[Resource("/companies/{companyId}/users/{id}", normalization_context=["groups"= [....]]), operations={}]
#[Resource(normalization_context=["groups"= [....]], operations=[
new Get(),
new Post(),
])]
class User
{
#[ApiProperty(identifier=true)]
Expand Down
2 changes: 1 addition & 1 deletion features/jsonld/context.feature
Expand Up @@ -80,7 +80,7 @@ Feature: JSON-LD contexts generation
"hydra": "http://www.w3.org/ns/hydra/core#",
"person": {
"@id": "http://example.com/id",
"@type": "@id",
"@var": "@id",
"foo": "bar"
}
}
Expand Down
101 changes: 101 additions & 0 deletions features/main/attribute_resource.feature
@@ -0,0 +1,101 @@
Feature: Resource attributes
In order to use the Resource attribute
As a developer
I should be able to fetch data from a state provider

@php8
@!mysql
@!mongodb
Scenario: Retrieve a Resource collection
When I add "Content-Type" header equal to "application/ld+json"
And I send a "GET" request to "/attribute_resources"
Then the response status code should be 200
And the response should be in JSON
And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8"
And the JSON should be equal to:
"""
{
"@context": "/contexts/AttributeResources",
"@id": "/attribute_resources",
"@type": "hydra:Collection",
"hydra:member": [
{
"@id": "/attribute_resources/1",
"@type": "AttributeResource",
"identifier": 1,
"name": "Foo"
},
{
"@id": "/attribute_resources/2",
"@type": "AttributeResource",
"identifier": 2,
"name": "Bar"
}
]
}
"""

@php8
@!mysql
@!mongodb
Scenario: Retrieve the first resource
When I add "Content-Type" header equal to "application/ld+json"
And I send a "GET" request to "/attribute_resources/1"
Then the response status code should be 200
And the response should be in JSON
And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8"
And the JSON should be equal to:
"""
{
"@context": "/contexts/AttributeResource",
"@id": "/attribute_resources/1",
"@type": "AttributeResource",
"identifier": 1,
"name": "Foo"
}
"""

@php8
@!mysql
@!mongodb
Scenario: Retrieve the aliased resource
When I add "Content-Type" header equal to "application/ld+json"
And I send a "GET" request to "/dummy/1/attribute_resources/2"
Then the response status code should be 200
And the response should be in JSON
And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8"
And the JSON should be equal to:
"""
{
"@context": "/contexts/AttributeResource",
"@id": "/dummy/1/attribute_resources/2",
"@type": "AttributeResource",
"identifier": 2,
"dummy": "/dummies/1",
"name": "Foo"
}
"""

@php8
@!mysql
@!mongodb
Scenario: Patch the aliased resource
When I add "Content-Type" header equal to "application/merge-patch+json"
And I send a "PATCH" request to "/dummy/1/attribute_resources/2" with body:
"""
{"name": "Patched"}
"""
Then the response status code should be 200
And the response should be in JSON
And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8"
And the JSON should be equal to:
"""
{
"@context": "/contexts/AttributeResource",
"@id": "/dummy/1/attribute_resources/2",
"@type": "AttributeResource",
"identifier": 2,
"dummy": "/dummies/1",
"name": "Patched"
}
"""
3 changes: 0 additions & 3 deletions phpstan.neon.dist
Expand Up @@ -94,9 +94,6 @@ parameters:
- '#UserPasswordHasherInterface#'

# Expected, due to PHP 8 attributes
- '#ReflectionProperty::getAttributes\(\)#'
- '#ReflectionMethod::getAttributes\(\)#'
- '#ReflectionClass<object>::getAttributes\(\)#'
- '#Constructor of class ApiPlatform\\Core\\Annotation\\ApiResource has an unused parameter#'
- '#Constructor of class ApiPlatform\\Core\\Annotation\\ApiProperty has an unused parameter#'

Expand Down
6 changes: 6 additions & 0 deletions phpunit.xml.dist
Expand Up @@ -16,6 +16,12 @@
<testsuites>
<testsuite name="Project Test Suite">
<directory>tests</directory>
<file phpVersion="8.0" phpVersionOperator=">=">tests/Metadata/Resource/Factory/ResourceCollectionMetadataFactoryTest.php</file>
<directory phpVersion="8.0" phpVersionOperator=">=">tests/Core</directory>
<directory phpVersion="8.0" phpVersionOperator=">=">tests/Metadata/ResourceCollection</directory>
<exclude>tests/Metadata/Resource/Factory/ResourceCollectionMetadataFactoryTest.php</exclude>
<exclude>tests/Metadata/ResourceCollection</exclude>
<exclude>tests/Core</exclude>
</testsuite>
</testsuites>

Expand Down
8 changes: 7 additions & 1 deletion src/Annotation/ApiProperty.php
Expand Up @@ -79,6 +79,11 @@ final class ApiProperty
*/
public $iri;

/**
* @var array
*/
public $types;

/**
* @var bool
*/
Expand Down Expand Up @@ -139,7 +144,8 @@ public function __construct(
?bool $push = null,
?string $security = null,
?array $swaggerContext = null,
?string $securityPostDenormalize = null
?string $securityPostDenormalize = null,
?array $types = null
) {
if (!\is_array($description)) { // @phpstan-ignore-line Doctrine annotations support
[$publicProperties, $configurableAttributes] = self::getConfigMetadata();
Expand Down
9 changes: 7 additions & 2 deletions src/Api/CachedIdentifiersExtractor.php
Expand Up @@ -24,7 +24,7 @@
*
* @author Antoine Bluchet <soyuka@gmail.com>
*/
final class CachedIdentifiersExtractor implements IdentifiersExtractorInterface
final class CachedIdentifiersExtractor implements ContextAwareIdentifiersExtractorInterface
{
use ResourceClassInfoTrait;

Expand Down Expand Up @@ -63,8 +63,13 @@ public function getIdentifiersFromResourceClass(string $resourceClass): array
/**
* {@inheritdoc}
*/
public function getIdentifiersFromItem($item): array
public function getIdentifiersFromItem($item, array $context = []): array
{
// TODO: Remove this class in 3.0 as the cache is not needed anymore
if (isset($context['identifiers']) && $this->decorated instanceof ContextAwareIdentifiersExtractorInterface) {
return $this->decorated->getIdentifiersFromItem($item, $context);
}

$keys = $this->getKeys($item, function ($item) use (&$identifiers) {
return $identifiers = $this->decorated->getIdentifiersFromItem($item);
});
Expand Down
38 changes: 38 additions & 0 deletions src/Api/ContextAwareIdentifiersExtractorInterface.php
@@ -0,0 +1,38 @@
<?php

/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <dunglas@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace ApiPlatform\Core\Api;

use ApiPlatform\Core\Exception\RuntimeException;

/**
* Extracts identifiers for a given Resource according to the retrieved Metadata.
*
* @author Antoine Bluchet <soyuka@gmail.com>
*/
interface ContextAwareIdentifiersExtractorInterface extends IdentifiersExtractorInterface
{
/**
* Finds identifiers from a Resource class.
*/
public function getIdentifiersFromResourceClass(string $resourceClass): array;

/**
* Finds identifiers from an Item (object).
*
* @param object $item
*
* @throws RuntimeException
*/
public function getIdentifiersFromItem($item, array $context = []): array;
}

0 comments on commit dd4b162

Please sign in to comment.