Skip to content

Commit

Permalink
Merge pull request #2679 from teohhanhui/fix/normalize-non-resource
Browse files Browse the repository at this point in the history
Normalize non-resource objects in a standalone normalizer
  • Loading branch information
soyuka authored Apr 6, 2019
2 parents 5272e3d + 521fa98 commit b7afbf8
Show file tree
Hide file tree
Showing 46 changed files with 1,306 additions and 736 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
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;
}
}
2 changes: 1 addition & 1 deletion features/doctrine/search_filter.feature
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Feature: Search filter on collections
},
"hydra:search": {
"@type": "hydra:IriTemplate",
"hydra:template": "\/dummy_cars{?availableAt[before],availableAt[strictly_before],availableAt[after],availableAt[strictly_after],canSell,foobar[],foobargroups[],foobargroups_override[],colors.prop,name}",
"hydra:template": "/dummy_cars{?availableAt[before],availableAt[strictly_before],availableAt[after],availableAt[strictly_after],canSell,foobar[],foobargroups[],foobargroups_override[],colors.prop,name}",
"hydra:variableRepresentation": "BasicRepresentation",
"hydra:mapping": [
{
Expand Down
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"
}
}
}
}
"""
107 changes: 0 additions & 107 deletions features/graphql/mutation.feature
Original file line number Diff line number Diff line change
Expand Up @@ -328,110 +328,3 @@ Feature: GraphQL mutation support
And the response should be in JSON
And the header "Content-Type" should be equal to "application/json"
And the JSON node "errors[0].message" should be equal to "name: This value should not be blank."

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"
}
}
}
"""
Loading

0 comments on commit b7afbf8

Please sign in to comment.