diff --git a/core/tests/Drupal/KernelTests/Core/Path/AliasWhitelistTest.php b/core/tests/Drupal/KernelTests/Core/Path/AliasWhitelistTest.php new file mode 100644 index 0000000000..1c14f69f52 --- /dev/null +++ b/core/tests/Drupal/KernelTests/Core/Path/AliasWhitelistTest.php @@ -0,0 +1,83 @@ +fixtures->createTables($connection); + + $memoryCounterBackend = new MemoryCounterBackend(); + + // Create AliasManager and Path object. + $aliasStorage = new AliasStorage($connection, $this->container->get('module_handler')); + $whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $aliasStorage); + $aliasManager = new AliasManager($aliasStorage, $whitelist, $this->container->get('language_manager'), $memoryCounterBackend); + + // Whitelist cache should not exist at all yet. + $this->assertFalse($memoryCounterBackend->get('path_alias_whitelist')); + + // Add an alias for an admin path and user path. + $aliasStorage->save('/admin/something', '/' . $this->randomMachineName()); + $aliasStorage->save('/user/something', '/' . $this->randomMachineName()); + $aliasManager->cacheClear(); + + // Lookup admin path in whitelist. It will query the DB and figure out + // that it indeed has an alias, and add it to the internal whitelist and + // flag it to be peristed to cache. + $this->assertTrue($whitelist->get('admin')); + + // Destruct the whitelist so it persists its cache. + $whitelist->destruct(); + $this->assertEquals($memoryCounterBackend->getCounter('set', 'path_alias_whitelist'), 1); + // Cache data should have data for 'user' and 'admin', even though just + // 'admin' was looked up. This is because the cache is primed with all + // menu router base paths. + $this->assertEquals(['user' => FALSE, 'admin' => TRUE], $memoryCounterBackend->get('path_alias_whitelist')->data); + $memoryCounterBackend->resetCounter(); + + // Re-initialize the the whitelist and lookup an alias for the 'user' path. + // Whitelist should load data from its cache, see that it hasn't done a + // check for 'user' yet, perform the check, then mark the result to be + // persisted to cache. + $whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $aliasStorage); + $this->assertTrue($whitelist->get('user')); + + // Delete the whitelist cache. This could happen from an outside process, + // like a code deployment that performs a cache rebuild. + $memoryCounterBackend->delete('path_alias_whitelist'); + + // Destruct whitelist so it saves to the whitelist data to cache. + // Usually it combines existing cache data with the new data, but we just + // cleared the existing cache data. + $whitelist->destruct(); + $this->assertEquals($memoryCounterBackend->getCounter('set', 'path_alias_whitelist'), 1); + + // Now, the data written to cache is corrupted. It contains data for + // the 'admin' path but not the 'user' path. + $this->assertEquals(['user' => TRUE], $memoryCounterBackend->get('path_alias_whitelist')->data); + + // Subsequent lookups for admin path will always return false, even though + // there ARE aliases for admin paths. Only way to fix is another cache + // clear. + $whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $aliasStorage); + $this->assertFalse($whitelist->get('admin')); + } + +}