Version 1
[yaffs-website] / web / core / tests / Drupal / Tests / Core / Form / FormCacheTest.php
diff --git a/web/core/tests/Drupal/Tests/Core/Form/FormCacheTest.php b/web/core/tests/Drupal/Tests/Core/Form/FormCacheTest.php
new file mode 100644 (file)
index 0000000..8b2734d
--- /dev/null
@@ -0,0 +1,434 @@
+<?php
+
+namespace Drupal\Tests\Core\Form;
+
+use Drupal\Core\Form\FormCache;
+use Drupal\Core\Form\FormState;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\Core\Form\FormCache
+ * @group Form
+ */
+class FormCacheTest extends UnitTestCase {
+
+  /**
+   * The form cache object under test.
+   *
+   * @var \Drupal\Core\Form\FormCache
+   */
+  protected $formCache;
+
+  /**
+   * The expirable key value factory.
+   *
+   * @var \Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $keyValueExpirableFactory;
+
+  /**
+   * The current user.
+   *
+   * @var \Drupal\Core\Session\AccountInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $account;
+
+  /**
+   * The CSRF token generator.
+   *
+   * @var \Drupal\Core\Access\CsrfTokenGenerator|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $csrfToken;
+
+  /**
+   * The mocked module handler.
+   *
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $moduleHandler;
+
+  /**
+   * The expirable key value store used by form cache.
+   *
+   * @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $formCacheStore;
+
+  /**
+   * The expirable key value store used by form state cache.
+   *
+   * @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $formStateCacheStore;
+
+  /**
+   * The logger channel.
+   *
+   * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $logger;
+
+  /**
+   * The request stack.
+   *
+   * @var \Symfony\Component\HttpFoundation\RequestStack|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $requestStack;
+
+  /**
+   * A policy rule determining the cacheability of a request.
+   *
+   * @var \Drupal\Core\PageCache\RequestPolicyInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $requestPolicy;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $runTestInSeparateProcess = TRUE;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $preserveGlobalState = FALSE;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
+
+    $this->formCacheStore = $this->getMock('Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface');
+    $this->formStateCacheStore = $this->getMock('Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface');
+    $this->keyValueExpirableFactory = $this->getMock('Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface');
+    $this->keyValueExpirableFactory->expects($this->any())
+      ->method('get')
+      ->will($this->returnValueMap([
+        ['form', $this->formCacheStore],
+        ['form_state', $this->formStateCacheStore],
+      ]));
+
+    $this->csrfToken = $this->getMockBuilder('Drupal\Core\Access\CsrfTokenGenerator')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $this->account = $this->getMock('Drupal\Core\Session\AccountInterface');
+
+    $this->logger = $this->getMock('Psr\Log\LoggerInterface');
+    $this->requestStack = $this->getMock('\Symfony\Component\HttpFoundation\RequestStack');
+    $this->requestPolicy = $this->getMock('\Drupal\Core\PageCache\RequestPolicyInterface');
+
+    $this->formCache = new FormCache($this->root, $this->keyValueExpirableFactory, $this->moduleHandler, $this->account, $this->csrfToken, $this->logger, $this->requestStack, $this->requestPolicy);
+  }
+
+  /**
+   * @covers ::getCache
+   */
+  public function testGetCacheValidToken() {
+    $form_build_id = 'the_form_build_id';
+    $form_state = new FormState();
+    $cache_token = 'the_cache_token';
+    $cached_form = ['#cache_token' => $cache_token];
+
+    $this->formCacheStore->expects($this->once())
+      ->method('get')
+      ->with($form_build_id)
+      ->willReturn($cached_form);
+    $this->csrfToken->expects($this->once())
+      ->method('validate')
+      ->with($cache_token)
+      ->willReturn(TRUE);
+    $this->account->expects($this->never())
+      ->method('isAnonymous');
+
+    $form = $this->formCache->getCache($form_build_id, $form_state);
+    $this->assertSame($cached_form, $form);
+  }
+
+  /**
+   * @covers ::getCache
+   */
+  public function testGetCacheInvalidToken() {
+    $form_build_id = 'the_form_build_id';
+    $form_state = new FormState();
+    $cache_token = 'the_cache_token';
+    $cached_form = ['#cache_token' => $cache_token];
+
+    $this->formCacheStore->expects($this->once())
+      ->method('get')
+      ->with($form_build_id)
+      ->willReturn($cached_form);
+    $this->csrfToken->expects($this->once())
+      ->method('validate')
+      ->with($cache_token)
+      ->willReturn(FALSE);
+    $this->account->expects($this->never())
+      ->method('isAnonymous');
+
+    $form = $this->formCache->getCache($form_build_id, $form_state);
+    $this->assertNull($form);
+  }
+
+  /**
+   * @covers ::getCache
+   */
+  public function testGetCacheAnonUser() {
+    $form_build_id = 'the_form_build_id';
+    $form_state = new FormState();
+    $cached_form = ['#cache_token' => NULL];
+
+    $this->formCacheStore->expects($this->once())
+      ->method('get')
+      ->with($form_build_id)
+      ->willReturn($cached_form);
+    $this->account->expects($this->once())
+      ->method('isAnonymous')
+      ->willReturn(TRUE);
+    $this->csrfToken->expects($this->never())
+      ->method('validate');
+
+    $form = $this->formCache->getCache($form_build_id, $form_state);
+    $this->assertSame($cached_form, $form);
+  }
+
+  /**
+   * @covers ::getCache
+   */
+  public function testGetCacheAuthUser() {
+    $form_build_id = 'the_form_build_id';
+    $form_state = new FormState();
+    $cached_form = ['#cache_token' => NULL];
+
+    $this->formCacheStore->expects($this->once())
+      ->method('get')
+      ->with($form_build_id)
+      ->willReturn($cached_form);
+    $this->account->expects($this->once())
+      ->method('isAnonymous')
+      ->willReturn(FALSE);
+
+    $form = $this->formCache->getCache($form_build_id, $form_state);
+    $this->assertNull($form);
+  }
+
+  /**
+   * @covers ::getCache
+   */
+  public function testGetCacheNoForm() {
+    $form_build_id = 'the_form_build_id';
+    $form_state = new FormState();
+    $cached_form = NULL;
+
+    $this->formCacheStore->expects($this->once())
+      ->method('get')
+      ->with($form_build_id)
+      ->willReturn($cached_form);
+    $this->account->expects($this->never())
+      ->method('isAnonymous');
+
+    $form = $this->formCache->getCache($form_build_id, $form_state);
+    $this->assertNull($form);
+  }
+
+  /**
+   * @covers ::getCache
+   */
+  public function testGetCacheImmutableForm() {
+    $form_build_id = 'the_form_build_id';
+    $form_state = (new FormState())
+      ->addBuildInfo('immutable', TRUE);
+    $cached_form = [
+      '#build_id' => 'the_old_build_form_id',
+    ];
+
+    $this->account->expects($this->once())
+      ->method('isAnonymous')
+      ->willReturn(TRUE);
+    $this->formCacheStore->expects($this->once())
+      ->method('get')
+      ->with($form_build_id)
+      ->willReturn($cached_form);
+
+    $form = $this->formCache->getCache($form_build_id, $form_state);
+    $this->assertSame($cached_form['#build_id'], $form['#build_id_old']);
+    $this->assertNotSame($cached_form['#build_id'], $form['#build_id']);
+    $this->assertSame($form['#build_id'], $form['form_build_id']['#value']);
+    $this->assertSame($form['#build_id'], $form['form_build_id']['#id']);
+  }
+
+  /**
+   * @covers ::loadCachedFormState
+   */
+  public function testLoadCachedFormState() {
+    $form_build_id = 'the_form_build_id';
+    $form_state = new FormState();
+    $cached_form = ['#cache_token' => NULL];
+
+    $this->formCacheStore->expects($this->once())
+      ->method('get')
+      ->with($form_build_id)
+      ->willReturn($cached_form);
+    $this->account->expects($this->once())
+      ->method('isAnonymous')
+      ->willReturn(TRUE);
+
+    $cached_form_state = ['storage' => ['foo' => 'bar']];
+    $this->formStateCacheStore->expects($this->once())
+      ->method('get')
+      ->with($form_build_id)
+      ->willReturn($cached_form_state);
+
+    $this->formCache->getCache($form_build_id, $form_state);
+    $this->assertSame($cached_form_state['storage'], $form_state->getStorage());
+  }
+
+  /**
+   * @covers ::loadCachedFormState
+   */
+  public function testLoadCachedFormStateWithFiles() {
+    $form_build_id = 'the_form_build_id';
+    $form_state = new FormState();
+    $cached_form = ['#cache_token' => NULL];
+
+    $this->formCacheStore->expects($this->once())
+      ->method('get')
+      ->with($form_build_id)
+      ->willReturn($cached_form);
+    $this->account->expects($this->once())
+      ->method('isAnonymous')
+      ->willReturn(TRUE);
+
+    $cached_form_state = ['build_info' => ['files' => [
+      [
+        'module' => 'a_module',
+        'type' => 'the_type',
+        'name' => 'some_name',
+      ],
+      [
+        'module' => 'another_module',
+      ],
+    ]]];
+    $this->moduleHandler->expects($this->at(0))
+      ->method('loadInclude')
+      ->with('a_module', 'the_type', 'some_name');
+    $this->moduleHandler->expects($this->at(1))
+      ->method('loadInclude')
+      ->with('another_module', 'inc', 'another_module');
+    $this->formStateCacheStore->expects($this->once())
+      ->method('get')
+      ->with($form_build_id)
+      ->willReturn($cached_form_state);
+
+    $this->formCache->getCache($form_build_id, $form_state);
+  }
+
+  /**
+   * @covers ::setCache
+   */
+  public function testSetCacheWithForm() {
+    $form_build_id = 'the_form_build_id';
+    $form = [
+      '#form_id' => 'the_form_id'
+    ];
+    $form_state = new FormState();
+
+    $this->formCacheStore->expects($this->once())
+      ->method('setWithExpire')
+      ->with($form_build_id, $form, $this->isType('int'));
+
+    $form_state_data = $form_state->getCacheableArray();
+    $this->formStateCacheStore->expects($this->once())
+      ->method('setWithExpire')
+      ->with($form_build_id, $form_state_data, $this->isType('int'));
+
+    $this->formCache->setCache($form_build_id, $form, $form_state);
+  }
+
+  /**
+   * @covers ::setCache
+   */
+  public function testSetCacheWithoutForm() {
+    $form_build_id = 'the_form_build_id';
+    $form = NULL;
+    $form_state = new FormState();
+
+    $this->formCacheStore->expects($this->never())
+      ->method('setWithExpire');
+
+    $form_state_data = $form_state->getCacheableArray();
+    $this->formStateCacheStore->expects($this->once())
+      ->method('setWithExpire')
+      ->with($form_build_id, $form_state_data, $this->isType('int'));
+
+    $this->formCache->setCache($form_build_id, $form, $form_state);
+  }
+
+  /**
+   * @covers ::setCache
+   */
+  public function testSetCacheAuthUser() {
+    $form_build_id = 'the_form_build_id';
+    $form = [];
+    $form_state = new FormState();
+
+    $cache_token = 'the_cache_token';
+    $form_data = $form;
+    $form_data['#cache_token'] = $cache_token;
+    $this->formCacheStore->expects($this->once())
+      ->method('setWithExpire')
+      ->with($form_build_id, $form_data, $this->isType('int'));
+
+    $form_state_data = $form_state->getCacheableArray();
+    $this->formStateCacheStore->expects($this->once())
+      ->method('setWithExpire')
+      ->with($form_build_id, $form_state_data, $this->isType('int'));
+
+    $this->csrfToken->expects($this->once())
+      ->method('get')
+      ->willReturn($cache_token);
+    $this->account->expects($this->once())
+      ->method('isAuthenticated')
+      ->willReturn(TRUE);
+
+    $this->formCache->setCache($form_build_id, $form, $form_state);
+  }
+
+  /**
+   * @covers ::setCache
+   */
+  public function testSetCacheBuildIdMismatch() {
+    $form_build_id = 'the_form_build_id';
+    $form = [
+      '#form_id' => 'the_form_id',
+      '#build_id' => 'stale_form_build_id',
+    ];
+    $form_state = new FormState();
+
+    $this->formCacheStore->expects($this->never())
+      ->method('setWithExpire');
+    $this->formStateCacheStore->expects($this->never())
+      ->method('setWithExpire');
+    $this->logger->expects($this->once())
+      ->method('error')
+      ->with('Form build-id mismatch detected while attempting to store a form in the cache.');
+    $this->formCache->setCache($form_build_id, $form, $form_state);
+  }
+
+
+  /**
+   * @covers ::deleteCache
+   */
+  public function testDeleteCache() {
+    $form_build_id = 'the_form_build_id';
+
+    $this->formCacheStore->expects($this->once())
+      ->method('delete')
+      ->with($form_build_id);
+    $this->formStateCacheStore->expects($this->once())
+      ->method('delete')
+      ->with($form_build_id);
+    $this->formCache->deleteCache($form_build_id);
+  }
+
+}