Problem/Motivation

    $cache_contexts_manager = $this->prophesize(CacheContextsManager::class);
    $cache_contexts_manager->assertValidTokens()->willReturn(TRUE);
    $cache_contexts_manager->reveal();

     $container = new Container();
    $container->set('cache_contexts_manager', $cache_contexts_manager);
     \Drupal::setContainer($container);

This puts something on the container but not what it expects because the revealed prophecy is dropped and not used. Additionally the assertValidTokens requires an argument that's not present.

Steps to reproduce

This is a code review so its a bit hard to reproduce without just reviewing the code. As for why the code currently "passes", we have to look at the code this is trying to support.

Cache.php

  public static function mergeContexts(array ...$cache_contexts) {
    $cache_contexts = array_unique(array_merge(...$cache_contexts));
    assert(\Drupal::service('cache_contexts_manager')->assertValidTokens($cache_contexts), sprintf('Failed to assert that "%s" are valid cache contexts.', implode(', ', $cache_contexts)));
    return $cache_contexts;
  }

This assertion expects true to confirm the cache context is valid. The ObjectProphecy that's currently a service returns itself from any method calls which is "truethy" which means the assertion accidentally passes.

Proposed resolution

Correct the usage of prophecy and improve the assertion of cache contexts.

Remaining tasks

User interface changes

n/a

API changes

n/a

Data model changes

n/a

Release notes snippet

n/a

Comments

neclimdul created an issue. See original summary.

neclimdul’s picture

Status: Active » Needs review
StatusFileSize
new3.22 KB
neclimdul’s picture


+    $this->cacheContextManager->assertValidTokens(['user.permissions'])->shouldBeCalled()->willReturn(TRUE);
+    $this->cacheContextManager->assertValidTokens(['user.permissions', 'user.node_grants:view'])->shouldBeCalled()->willReturn(TRUE);
     $node_access_result = AccessResult::allowed()->cachePerPermissions()->addCacheContexts(['user.node_grants:view']);
 

Haven't looked at why this gets called twice with different values but its the current behavior. Maybe exposing a follow up bug/optimization though.

phenaproxima’s picture

Status: Needs review » Reviewed & tested by the community

This makes perfect sense to me and I think the addition of the shouldBeCalled() checks will prevent this from regressing.

  • catch committed 51a8a4f on 10.0.x
    Issue #3321955 by neclimdul, phenaproxima:...
  • catch committed 5f612de on 10.1.x
    Issue #3321955 by neclimdul, phenaproxima:...
  • catch committed 1092697 on 9.5.x
    Issue #3321955 by neclimdul, phenaproxima:...
catch’s picture

Version: 10.1.x-dev » 9.5.x-dev
Status: Reviewed & tested by the community » Fixed

Committed/pushed to 10.1.x and cherry-picked back through to 9.5.x, thanks!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.