Skip to content

Commit 01d1bc9

Browse files
committed
fix(dataproducer): CurrentUser result is uncacheable
1 parent b37fd9e commit 01d1bc9

File tree

2 files changed

+97
-5
lines changed

2 files changed

+97
-5
lines changed

src/Plugin/GraphQL/DataProducer/User/CurrentUser.php

+5-5
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public static function create(ContainerInterface $container, array $configuratio
4242
}
4343

4444
/**
45-
* CurrentUser constructor.
45+
* Constructs a new CurrentUser data producer.
4646
*
4747
* @param array $configuration
4848
* A configuration array containing information about the plugin instance.
@@ -59,7 +59,7 @@ public function __construct(array $configuration, string $plugin_id, array $plug
5959
}
6060

6161
/**
62-
* Returns current user.
62+
* Returns the current user.
6363
*
6464
* @param \Drupal\graphql\GraphQL\Execution\FieldContext $field_context
6565
* Field context.
@@ -68,9 +68,9 @@ public function __construct(array $configuration, string $plugin_id, array $plug
6868
* The current user.
6969
*/
7070
public function resolve(FieldContext $field_context): AccountInterface {
71-
// Response must be cached based on current user as a cache context,
72-
// otherwise a new user would became a previous user.
73-
$field_context->addCacheableDependency($this->currentUser);
71+
// Response must be cached per user so that information from previously
72+
// logged in users will not leak to newly logged in users.
73+
$field_context->addCacheContexts(['user']);
7474
return $this->currentUser;
7575
}
7676

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Drupal\Tests\graphql\Kernel\DataProducer;
6+
7+
use Drupal\Core\Session\AccountInterface;
8+
use Drupal\Tests\graphql\Kernel\GraphQLTestBase;
9+
use Drupal\Tests\user\Traits\UserCreationTrait;
10+
use Drupal\graphql\GraphQL\Execution\FieldContext;
11+
use Drupal\user\Entity\User;
12+
13+
/**
14+
* Tests the current_user data producer.
15+
*
16+
* @coversDefaultClass \Drupal\graphql\Plugin\GraphQL\DataProducer\User\CurrentUser
17+
* @group graphql
18+
*/
19+
class CurrentUserTest extends GraphQLTestBase {
20+
21+
use UserCreationTrait;
22+
23+
/**
24+
* Test users.
25+
*
26+
* @var \Drupal\Core\Session\AccountInterface[]
27+
*/
28+
protected array $users;
29+
30+
/**
31+
* {@inheritdoc}
32+
*/
33+
protected function setUp(): void {
34+
parent::setUp();
35+
36+
// Create two test users.
37+
$this->users = [
38+
$this->createUser(),
39+
$this->createUser(),
40+
];
41+
42+
// Log out initially.
43+
$this->container->get('current_user')->setAccount(User::getAnonymousUser());
44+
}
45+
46+
/**
47+
* @covers \Drupal\graphql\Plugin\GraphQL\DataProducer\User\CurrentUser::resolve
48+
*/
49+
public function testCurrentUser(): void {
50+
// Initially no user is logged in.
51+
$result = $this->executeDataProducer('current_user');
52+
$this->assertInstanceOf(AccountInterface::class, $result);
53+
$this->assertEquals(0, $result->id());
54+
55+
// Log in as the first user.
56+
$this->container->get('current_user')->setAccount($this->users[0]);
57+
$result = $this->executeDataProducer('current_user');
58+
$this->assertInstanceOf(AccountInterface::class, $result);
59+
$this->assertEquals($this->users[0]->id(), $result->id());
60+
61+
// Log in as the second user.
62+
$this->container->get('current_user')->setAccount($this->users[1]);
63+
$result = $this->executeDataProducer('current_user');
64+
$this->assertInstanceOf(AccountInterface::class, $result);
65+
$this->assertEquals($this->users[1]->id(), $result->id());
66+
67+
// Log out again.
68+
$this->container->get('current_user')->setAccount(User::getAnonymousUser());
69+
$result = $this->executeDataProducer('current_user');
70+
$this->assertInstanceOf(AccountInterface::class, $result);
71+
$this->assertEquals(0, $result->id());
72+
}
73+
74+
/**
75+
* {@inheritdoc}
76+
*/
77+
protected function executeDataProducer($id, array $contexts = []) {
78+
/** @var \Drupal\graphql\Plugin\DataProducerPluginManager $manager */
79+
$manager = $this->container->get('plugin.manager.graphql.data_producer');
80+
81+
/** @var \Drupal\graphql\Plugin\DataProducerPluginInterface $plugin */
82+
$plugin = $manager->createInstance($id);
83+
84+
// The 'user' cache context should be added so that the results will be
85+
// cached per user.
86+
$context = $this->prophesize(FieldContext::class);
87+
$context->addCacheContexts(['user'])->willReturn($context->reveal())->shouldBeCalled();
88+
89+
return $plugin->resolveField($context->reveal());
90+
}
91+
92+
}

0 commit comments

Comments
 (0)