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
Comment #2
neclimdulComment #3
neclimdulHaven't looked at why this gets called twice with different values but its the current behavior. Maybe exposing a follow up bug/optimization though.
Comment #4
phenaproximaThis makes perfect sense to me and I think the addition of the
shouldBeCalled()checks will prevent this from regressing.Comment #6
catchCommitted/pushed to 10.1.x and cherry-picked back through to 9.5.x, thanks!