CacheableMetadataCalculationTest.php 3.28 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
<?php

namespace Drupal\Tests\views\Kernel;

use Drupal\KernelTests\KernelTestBase;

/**
 * Tests that cacheability metadata is only calculated when needed.
 *
 * @group views
 */
12
class CacheableMetadataCalculationTest extends KernelTestBase {
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

  /**
   * The ID of the view used in the test.
   */
  const TEST_VIEW_ID = 'test_cacheable_metadata_calculation';

  /**
   * The ID of the module used in the test.
   */
  const TEST_MODULE = 'views_test_cacheable_metadata_calculation';

  /**
   * The state service.
   *
   * @var \Drupal\Core\State\StateInterface
   */
  protected $state;

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * {@inheritdoc}
   */
  protected static $modules = ['system', 'views', 'user'];

  /**
   * {@inheritdoc}
   */
46
  protected function setUp(): void {
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
    parent::setUp();

    $this->installConfig(['views']);
    $this->installEntitySchema('user');

    $this->state = $this->container->get('state');
    $this->entityTypeManager = $this->container->get('entity_type.manager');
  }

  /**
   * Tests that cacheability metadata is only calculated when needed.
   *
   * Determining the cacheability of a view is an expensive operation since it
   * requires all Views plugins and handlers to be initialized. For efficiency
   * reasons this should only be done if a view is being saved (either through
   * the UI or the API). The cacheability metadata is then stored in the view
   * config and is ready to use at runtime.
   *
   * It should not be calculated when a view is enabled through installing a
   * module, or by syncing configuration.
   *
   * @see \Drupal\views\Entity\View::addCacheMetadata()
   */
  public function testCacheableMetadataCalculation() {
    // Enabling a module that contains a view should not cause the cacheability
    // metadata to be recalculated.
    $this->enableModules([self::TEST_MODULE]);
    $this->installConfig([self::TEST_MODULE]);
75
    $this->assertCacheableMetadataHasBeenCalculated(FALSE);
76
77
78
79
80
81

    // When a view is saved normally we have to recalculate the cacheability
    // metadata, since it is possible changes have been made to the view that
    // affect cacheability.
    $view = $this->entityTypeManager->getStorage('view')->load(self::TEST_VIEW_ID);
    $view->save();
82
    $this->assertCacheableMetadataHasBeenCalculated(TRUE);
83
84
85
86
87
88
    $this->resetState();

    // When a view is being saved due to config being synchronized, the
    // cacheability metadata doesn't change so it should not be recalculated.
    $view->setSyncing(TRUE);
    $view->save();
89
    $this->assertCacheableMetadataHasBeenCalculated(FALSE);
90
91
92
93
94
95
96
97
98
  }

  /**
   * Checks whether the view has calculated its cacheability metadata.
   *
   * @param bool $expected_result
   *   TRUE if it is expected that the cacheability metadata has been
   *   calculated. FALSE otherwise.
   */
99
  protected function assertCacheableMetadataHasBeenCalculated($expected_result) {
100
101
102
103
104
105
106
107
108
109
110
111
    $this->state->resetCache();
    $this->assertEquals($expected_result, $this->state->get('views_test_cacheable_metadata_has_been_accessed'));
  }

  /**
   * Resets the state so we are ready for a new test.
   */
  protected function resetState() {
    $this->state->set('views_test_cacheable_metadata_has_been_accessed', FALSE);
  }

}