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 18 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
82 changes: 73 additions & 9 deletions tests/Integration/Schema/Directives/CreateDirectiveTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class CreateDirectiveTest extends DBTestCase
{
public function testCanCreateFromFieldArguments(): void
{
$this->schema .= /** @lang GraphQL */ '
$this->schema .= /** @lang GraphQL */'
megawubs marked this conversation as resolved.
Show resolved Hide resolved
type Company {
id: ID!
name: String!
Expand Down Expand Up @@ -41,7 +41,7 @@ public function testCanCreateFromFieldArguments(): void

public function testCanCreateFromInputObject(): void
{
$this->schema .= /** @lang GraphQL */ '
$this->schema .= /** @lang GraphQL */'
type Company {
id: ID!
name: String!
Expand Down Expand Up @@ -77,7 +77,7 @@ public function testCanCreateFromInputObject(): void

public function testCreatesAnEntryWithDatabaseDefaultsAndReturnsItImmediately(): void
{
$this->schema .= /** @lang GraphQL */ '
$this->schema .= /** @lang GraphQL */'
type Mutation {
createTag(name: String): Tag @create
}
Expand Down Expand Up @@ -111,7 +111,7 @@ public function testDoesNotCreateWithFailingRelationship(): void

$this->app['config']->set('app.debug', false);

$this->schema .= /** @lang GraphQL */ '
$this->schema .= /** @lang GraphQL */'
type Task {
id: ID!
name: String!
Expand Down Expand Up @@ -178,7 +178,7 @@ public function testCreatesOnPartialFailureWithTransactionsDisabled(): void
$this->app['config']->set('app.debug', false);
config(['lighthouse.transactional_mutations' => false]);

$this->schema .= /** @lang GraphQL */ '
$this->schema .= /** @lang GraphQL */'
type Task {
id: ID!
name: String!
Expand Down Expand Up @@ -244,7 +244,7 @@ public function testCreatesOnPartialFailureWithTransactionsDisabled(): void

public function testDoesNotFailWhenPropertyNameMatchesModelsNativeMethods(): void
{
$this->schema .= /** @lang GraphQL */ '
$this->schema .= /** @lang GraphQL */'
type Task {
id: ID!
name: String!
Expand Down Expand Up @@ -307,7 +307,7 @@ public function testDoesNotFailWhenPropertyNameMatchesModelsNativeMethods(): voi

public function testNestedArgResolverHasMany(): void
{
$this->schema .= /** @lang GraphQL */ '
$this->schema .= /** @lang GraphQL */'
type Mutation {
createUser(input: CreateUserInput! @spread): User @create
}
Expand Down Expand Up @@ -361,7 +361,7 @@ public function testNestedArgResolverHasMany(): void

public function testNestedArgResolverForOptionalBelongsTo(): void
{
$this->schema .= /** @lang GraphQL */ '
$this->schema .= /** @lang GraphQL */'
type Mutation {
createTask(input: CreateTaskInput! @spread): Task @create
}
Expand Down Expand Up @@ -413,7 +413,7 @@ public function testNestedArgResolverForOptionalBelongsTo(): void

public function testCanCreateTwice(): void
{
$this->schema .= /** @lang GraphQL */ '
$this->schema .= /** @lang GraphQL */'
type Task {
id: ID!
name: String!
Expand Down 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',
],
],
],
],
]);
}
}
98 changes: 88 additions & 10 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 @@ -139,7 +139,7 @@ public function testDoesNotUpdateWithFailingRelationship(): void
{
factory(User::class)->create(['name' => 'Original']);

$this->schema .= /** @lang GraphQL */ '
$this->schema .= /** @lang GraphQL */'
type Task {
id: ID!
name: String!
Expand Down Expand Up @@ -202,27 +202,27 @@ public function testNestedArgResolver(): void
'id' => 3,
]);

$this->schema .= /** @lang GraphQL */ '
$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
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',
],
],
],
],
]);
}
}
Loading