Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix nested create, upsert and update on lists of inputs #1316

Merged
merged 22 commits into from
Apr 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ You can find and compare releases at the [GitHub release page](https://github.co
- Fix nested mutations with multiple `belongsTo` relations at the same level https://github.com/nuwave/lighthouse/pull/1285
- Avoid race condition that occurs when using `Cache::has()` https://github.com/nuwave/lighthouse/pull/1290
- Replace usage of `resolve()` helper with Lumen-compatible `app()` https://github.com/nuwave/lighthouse/pull/1305
- Fix using `@create` and `@update` on nested input object fields that accept an array of input types
https://github.com/nuwave/lighthouse/pull/1316

### Changed

Expand Down
4 changes: 2 additions & 2 deletions src/Schema/Directives/MutationExecutorDirective.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public function __invoke($parent, $args)
}

/**
* @param \Nuwave\Lighthouse\Execution\Arguments\ArgumentSet|\Nuwave\Lighthouse\Execution\Arguments\ArgumentSet[]
* @param \Nuwave\Lighthouse\Execution\Arguments\ArgumentSet|\Nuwave\Lighthouse\Execution\Arguments\ArgumentSet[] $args
* @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Model[]
*/
protected function executeMutation(Model $model, $args, ?Relation $parentRelation = null)
Expand All @@ -98,7 +98,7 @@ protected function executeMutation(Model $model, $args, ?Relation $parentRelatio

return Utils::applyEach(
static function (ArgumentSet $argumentSet) use ($update, $model) {
return $update($model, $argumentSet);
return $update($model->newInstance(), $argumentSet);
},
$args
);
Expand Down
2 changes: 1 addition & 1 deletion tests/Integration/Schema/Directives/CacheDirectiveTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public function testCanPlaceCacheKeyOnAnyField(): void
'email' => 'foo@bar.com',
]);

$this->schema = /** @lang GraphQL */'
$this->schema = /** @lang GraphQL */ '
type User {
id: ID!
name: String @cache
Expand Down
64 changes: 64 additions & 0 deletions tests/Integration/Schema/Directives/CreateDirectiveTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -485,4 +485,68 @@ public function testCanCreateTwice(): void
],
]);
}

public function testCanCreateTwiceWithCreateDirective(): void
{
$this->schema .= /** @lang GraphQL */ '
type Task {
id: ID!
name: String!
}

type User {
id: ID!
name: String
tasks: [Task!]! @hasMany
}

type Mutation {
createUser(input: CreateUserInput! @spread): User @create
}

input CreateUserInput {
name: String
tasks: [CreateTaskInput!] @create
}

input CreateTaskInput {
name: String
}
';

$this->graphQL(/** @lang GraphQL */ '
mutation {
createUser(input: {
name: "foo"
tasks: [
{
name: "fooTask"
},
{
name: "barTask"
}
]
}) {
name
tasks {
name
}
}
}
')->assertJson([
'data' => [
'createUser' => [
'name' => 'foo',
'tasks' => [
[
'name' => 'fooTask',
],
[
'name' => 'barTask',
],
],
],
],
]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ public function testRelayTypeIsLimitedToMaxCountFromConfig(): void
{
config(['lighthouse.paginate_max_count' => 2]);

$this->schema = /** @lang GraphQL */'
$this->schema = /** @lang GraphQL */ '
type User {
tasks: [Task!]! @hasMany(type: "relay")
}
Expand Down
94 changes: 86 additions & 8 deletions tests/Integration/Schema/Directives/UpdateDirectiveTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public function testCanUpdateFromFieldArguments(): void
{
factory(Company::class)->create(['name' => 'foo']);

$this->schema .= '
$this->schema .= /** @lang GraphQL */ '
type Company {
id: ID!
name: String!
Expand All @@ -29,7 +29,7 @@ public function testCanUpdateFromFieldArguments(): void
}
';

$this->graphQL('
$this->graphQL(/** @lang GraphQL */ '
mutation {
updateCompany(
id: 1
Expand All @@ -55,7 +55,7 @@ public function testCanUpdateFromInputObject(): void
{
factory(Company::class)->create(['name' => 'foo']);

$this->schema .= '
$this->schema .= /** @lang GraphQL */ '
type Company {
id: ID!
name: String!
Expand Down Expand Up @@ -99,7 +99,7 @@ public function testCanUpdateWithCustomPrimaryKey(): void
{
factory(Category::class)->create(['name' => 'foo']);

$this->schema .= '
$this->schema .= /** @lang GraphQL */ '
type Category {
category_id: ID!
name: String!
Expand Down Expand Up @@ -206,23 +206,23 @@ public function testNestedArgResolver(): void
type Mutation {
updateUser(input: UpdateUserInput! @spread): User @update
}

type Task {
id: Int
name: String!
}

type User {
name: String
tasks: [Task!]! @hasMany
}

input UpdateUserInput {
id: Int
name: String
updateTask: UpdateTaskInput @update(relation: "tasks")
}

input UpdateTaskInput {
id: Int
name: String
Expand Down Expand Up @@ -260,4 +260,82 @@ public function testNestedArgResolver(): void
],
]);
}

public function testNestedUpdateOnInputList(): void
{
factory(User::class)->create();
factory(Task::class)->create([
'id' => 3,
]);
factory(Task::class)->create([
'id' => 4,
]);

$this->schema .= /** @lang GraphQL */ '
type Mutation {
updateUser(input: UpdateUserInput! @spread): User @update
}

type Task {
id: Int
name: String!
}

type User {
name: String
tasks: [Task!]! @hasMany
}

input UpdateUserInput {
id: Int
name: String
updateTask: [UpdateTaskInput] @update(relation: "tasks")
}

input UpdateTaskInput {
id: Int
name: String
}
';

$this->graphQL(/** @lang GraphQL */ '
mutation {
updateUser(input: {
id: 1
name: "foo"
updateTask: [
{
id: 3
name: "Uniq"
},
{
id: 4,
name: "Foo"
}
]
}) {
name
tasks {
id
name
}
}
}
')->assertExactJson([
'data' => [
'updateUser' => [
'name' => 'foo',
'tasks' => [
[
'id' => 3,
'name' => 'Uniq',
], [
'id' => 4,
'name' => 'Foo',
],
],
],
],
]);
}
}
74 changes: 70 additions & 4 deletions tests/Integration/Schema/Directives/UpsertDirectiveTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,23 @@ public function testNestedArgResolver(): void
type Mutation {
updateUser(input: UpdateUserInput! @spread): User @update
}

type Task {
id: Int
name: String!
}

type User {
name: String
tasks: [Task!]! @hasMany
}

input UpdateUserInput {
id: Int
name: String
tasks: [UpdateTaskInput!] @upsert(relation: "tasks")
}

input UpdateTaskInput {
id: Int
name: String
Expand Down Expand Up @@ -84,4 +84,70 @@ public function testNestedArgResolver(): void
],
]);
}

public function testNestedInsertOnInputList(): void
{
factory(User::class)->create();
$this->schema .= /** @lang GraphQL */ '
type Mutation {
updateUser(input: UpdateUserInput! @spread): User @update
}

type Task {
id: Int
name: String!
}

type User {
name: String
tasks: [Task!]! @hasMany
}

input UpdateUserInput {
id: Int
name: String
tasks: [UpdateTaskInput!] @upsert(relation: "tasks")
}

input UpdateTaskInput {
id: Int
name: String
}
';

$this->graphQL(/** @lang GraphQL */ '
mutation {
updateUser(input: {
id: 1
name: "foo"
tasks: [
{
name: "foo"
}
{
name: "bar"
}
]
}) {
name
tasks {
name
}
}
}')->assertExactJson([
'data' => [
'updateUser' => [
'name' => 'foo',
'tasks' => [
[
'name' => 'foo',
],
[
'name' => 'bar',
],
],
],
],
]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

class WhereHasConditionsDirectiveTest extends DBTestCase
{
protected $schema = /** @lang GraphQL */'
protected $schema = /** @lang GraphQL */ '
type User {
id: ID!
name: String
Expand Down