Skip to content

Commit

Permalink
Merge pull request #2704 from soyuka/merge-2.4
Browse files Browse the repository at this point in the history
Merge 2.4
  • Loading branch information
soyuka committed Apr 7, 2019
2 parents a1da24c + d442702 commit 44a686c
Show file tree
Hide file tree
Showing 75 changed files with 1,975 additions and 680 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ jobs:
mkdir -p build/logs/tmp build/cov
for f in $(find features -name '*.feature' -not -path 'features/main/exposed_state.feature' -not -path 'features/elasticsearch/*' -not -path 'features/mongodb/*' | circleci tests split --split-by=timings); do
_f=${f//\//_}
FEATURE="${_f}" phpdbg -qrr vendor/bin/behat --profile=coverage --suite=default --format=progress --out=std --format=junit --out=build/logs/tmp/"${_f}" "$f"
FEATURE="${_f}" phpdbg -qrr vendor/bin/behat --profile=coverage --suite=default --format=progress --out=std --format=junit --out=build/logs/tmp/"${_f}" --no-interaction "$f"
done
- run:
name: Merge Behat test reports
Expand Down
8 changes: 4 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ script:
fi
- tests/Fixtures/app/console cache:clear
- if [[ $APP_ENV = 'postgres' ]]; then
vendor/bin/behat --suite=postgres --format=progress;
vendor/bin/behat --suite=postgres --format=progress --no-interaction;
elif [[ $APP_ENV = 'mongodb' ]]; then
vendor/bin/behat --suite=mongodb --format=progress;
vendor/bin/behat --suite=mongodb --format=progress --no-interaction;
elif [[ $APP_ENV = 'elasticsearch' ]]; then
vendor/bin/behat --suite=elasticsearch --format=progress;
vendor/bin/behat --suite=elasticsearch --format=progress --no-interaction;
else
vendor/bin/behat --suite=default --format=progress;
vendor/bin/behat --suite=default --format=progress --no-interaction;
fi
- tests/Fixtures/app/console api:swagger:export > swagger.json && npx swagger-cli validate swagger.json && rm swagger.json
- tests/Fixtures/app/console api:swagger:export --yaml > swagger.yaml && npx swagger-cli validate swagger.yaml && rm swagger.yaml
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@ services:

test_script:
- cd %APPVEYOR_BUILD_FOLDER%
- php vendor\behat\behat\bin\behat --format=progress --suite=default
- php vendor\behat\behat\bin\behat --format=progress --suite=default --no-interaction
- rmdir tests\Fixtures\app\var\cache /s /q
- php vendor\phpunit\phpunit\phpunit
35 changes: 35 additions & 0 deletions features/bootstrap/DoctrineContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@

declare(strict_types=1);

use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\Address as AddressDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\Answer as AnswerDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\CompositeItem as CompositeItemDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\CompositeLabel as CompositeLabelDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\CompositePrimitiveItem as CompositePrimitiveItemDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\CompositeRelation as CompositeRelationDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\Customer as CustomerDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\Dummy as DummyDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\DummyAggregateOffer as DummyAggregateOfferDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\DummyCar as DummyCarDocument;
Expand All @@ -39,6 +41,7 @@
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\FourthLevel as FourthLevelDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\Greeting as GreetingDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\MaxDepthDummy as MaxDepthDummyDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\Order as OrderDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\Person as PersonDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\PersonToPet as PersonToPetDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\Pet as PetDocument;
Expand All @@ -52,12 +55,14 @@
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\SoMany as SoManyDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\ThirdLevel as ThirdLevelDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\User as UserDocument;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Address;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Answer;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\CompositeItem;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\CompositeLabel;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\CompositePrimitiveItem;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\CompositeRelation;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Container;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Customer;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Dummy;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyAggregateOffer;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyCar;
Expand All @@ -83,6 +88,7 @@
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Greeting;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\MaxDepthDummy;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Node;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Order;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Person;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\PersonToPet;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Pet;
Expand Down Expand Up @@ -1571,4 +1577,33 @@ private function buildThirdLevel()
{
return $this->isOrm() ? new ThirdLevel() : new ThirdLevelDocument();
}

/**
* @Given there is a order with same customer and receiver
*/
public function testEagerLoadingNotDuplicateRelation()
{
$customer = $this->isOrm() ? new Customer() : new CustomerDocument();
$customer->name = 'customer_name';

$address1 = $this->isOrm() ? new Address() : new AddressDocument();
$address1->name = 'foo';
$address2 = $this->isOrm() ? new Address() : new AddressDocument();
$address2->name = 'bar';

$order = $this->isOrm() ? new Order() : new OrderDocument();
$order->recipient = $customer;
$order->customer = $customer;

$customer->addresses->add($address1);
$customer->addresses->add($address2);

$this->manager->persist($address1);
$this->manager->persist($address2);
$this->manager->persist($customer);
$this->manager->persist($order);

$this->manager->flush();
$this->manager->clear();
}
}
42 changes: 21 additions & 21 deletions features/bootstrap/JsonContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,27 +24,6 @@ public function __construct(HttpCallResultPool $httpCallResultPool)
parent::__construct($httpCallResultPool);
}

private function sortArrays($obj)
{
$isObject = is_object($obj);

foreach ($obj as $key => $value) {
if (null === $value || is_scalar($value)) {
continue;
}

if (is_array($value)) {
sort($value);
}

$value = $this->sortArrays($value);

$isObject ? $obj->{$key} = $value : $obj[$key] = $value;
}

return $obj;
}

/**
* @Then /^the JSON should be deep equal to:$/
*/
Expand Down Expand Up @@ -75,4 +54,25 @@ public function theJsonIsASupersetOf(PyStringNode $content)
$actual = json_decode($this->httpCallResultPool->getResult()->getValue(), true);
Assert::assertArraySubset(json_decode($content->getRaw(), true), $actual);
}

private function sortArrays($obj)
{
$isObject = is_object($obj);

foreach ($obj as $key => $value) {
if (null === $value || is_scalar($value)) {
continue;
}

if (is_array($value)) {
sort($value);
}

$value = $this->sortArrays($value);

$isObject ? $obj->{$key} = $value : $obj[$key] = $value;
}

return $obj;
}
}
190 changes: 190 additions & 0 deletions features/graphql/input_output.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
Feature: GraphQL DTO input and output
In order to use a hypermedia API
As a client software developer
I need to be able to use DTOs on my resources as Input or Output objects.

@createSchema
Scenario: Retrieve an Output with GraphQl
When I add "Content-Type" header equal to "application/ld+json"
And I send a "POST" request to "/dummy_dto_input_outputs" with body:
"""
{
"foo": "test",
"bar": 1
}
"""
Then the response status code should be 201
And the JSON should be equal to:
"""
{
"@context": {
"@vocab": "http://example.com/docs.jsonld#",
"hydra": "http://www.w3.org/ns/hydra/core#",
"id": "OutputDto/id",
"baz": "OutputDto/baz",
"bat": "OutputDto/bat"
},
"@type": "DummyDtoInputOutput",
"@id": "/dummy_dto_input_outputs/1",
"id": 1,
"baz": 1,
"bat": "test"
}
"""
When I send the following GraphQL request:
"""
{
dummyDtoInputOutput(id: "/dummy_dto_input_outputs/1") {
_id, id, baz
}
}
"""
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/json"
And the JSON should be equal to:
"""
{
"data": {
"dummyDtoInputOutput": {
"_id": 1,
"id": "/dummy_dto_input_outputs/1",
"baz": 1
}
}
}
"""

Scenario: Create an item using custom inputClass & disabled outputClass
Given there are 2 dummyDtoNoOutput objects
When I send the following GraphQL request:
"""
mutation {
createDummyDtoNoOutput(input: {foo: "A new one", bar: 3, clientMutationId: "myId"}) {
dummyDtoNoOutput {
id
}
clientMutationId
}
}
"""
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/json"
And the JSON should be equal to:
"""
{
"errors": [
{
"message": "Cannot query field \"id\" on type \"DummyDtoNoOutput\".",
"extensions": {
"category": "graphql"
},
"locations": [
{
"line": 4,
"column": 7
}
]
}
]
}
"""

Scenario: Cannot create an item with input fields using disabled inputClass
When I send the following GraphQL request:
"""
mutation {
createDummyDtoNoInput(input: {lorem: "A new one", ipsum: 3, clientMutationId: "myId"}) {
clientMutationId
}
}
"""
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/json"
And the JSON should be equal to:
"""
{
"errors": [
{
"message": "Field \"lorem\" is not defined by type createDummyDtoNoInputInput.",
"extensions": {
"category": "graphql"
},
"locations": [
{
"line": 2,
"column": 33
}
]
},
{
"message": "Field \"ipsum\" is not defined by type createDummyDtoNoInputInput.",
"extensions": {
"category": "graphql"
},
"locations": [
{
"line": 2,
"column": 53
}
]
}
]
}
"""

Scenario: Create an item with empty input fields using disabled inputClass (no persist done)
When I send the following GraphQL request:
"""
mutation {
createDummyDtoNoInput(input: {clientMutationId: "myId"}) {
dummyDtoNoInput {
id
}
clientMutationId
}
}
"""
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/json"
And the JSON should be equal to:
"""
{
"data": {
"createDummyDtoNoInput": {
"dummyDtoNoInput": null,
"clientMutationId": "myId"
}
}
}
"""

@!mongodb
Scenario: Use messenger with graphql and an input where the handler gives a synchronous result
When I send the following GraphQL request:
"""
mutation {
createMessengerWithInput(input: {var: "test"}) {
messengerWithInput { id, name }
}
}
"""
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/json"
And the JSON should be equal to:
"""
{
"data": {
"createMessengerWithInput": {
"messengerWithInput": {
"id": "/messenger_with_inputs/1",
"name": "test"
}
}
}
}
"""
9 changes: 7 additions & 2 deletions features/graphql/mutation.feature
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ Feature: GraphQL mutation support
type {
name
kind
ofType {
name
kind
}
}
}
}
Expand All @@ -31,8 +35,9 @@ Feature: GraphQL mutation support
And the JSON node "data.__type.fields[0].type.name" should match "/^delete[A-z0-9]+Payload$/"
And the JSON node "data.__type.fields[0].type.kind" should be equal to "OBJECT"
And the JSON node "data.__type.fields[0].args[0].name" should be equal to "input"
And the JSON node "data.__type.fields[0].args[0].type.name" should match "/^delete[A-z0-9]+Input$/"
And the JSON node "data.__type.fields[0].args[0].type.kind" should be equal to "INPUT_OBJECT"
And the JSON node "data.__type.fields[0].args[0].type.kind" should be equal to "NON_NULL"
And the JSON node "data.__type.fields[0].args[0].type.ofType.name" should match "/^delete[A-z0-9]+Input$/"
And the JSON node "data.__type.fields[0].args[0].type.ofType.kind" should be equal to "INPUT_OBJECT"

Scenario: Create an item
When I send the following GraphQL request:
Expand Down
Loading

0 comments on commit 44a686c

Please sign in to comment.